/***************************************************************
Copyright Statement:

This software/firmware and related documentation (EcoNet Software) 
are protected under relevant copyright laws. The information contained herein 
is confidential and proprietary to EcoNet (HK) Limited (EcoNet) and/or 
its licensors. Without the prior written permission of EcoNet and/or its licensors, 
any reproduction, modification, use or disclosure of EcoNet Software, and 
information contained herein, in whole or in part, shall be strictly prohibited.

EcoNet (HK) Limited  EcoNet. ALL RIGHTS RESERVED.

BY OPENING OR USING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY 
ACKNOWLEDGES AND AGREES THAT THE SOFTWARE/FIRMWARE AND ITS 
DOCUMENTATIONS (ECONET SOFTWARE) RECEIVED FROM ECONET 
AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON AN AS IS 
BASIS ONLY. ECONET EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, 
WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, 
OR NON-INFRINGEMENT. NOR DOES ECONET PROVIDE ANY WARRANTY 
WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTIES WHICH 
MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE ECONET SOFTWARE. 
RECEIVER AGREES TO LOOK ONLY TO SUCH THIRD PARTIES FOR ANY AND ALL 
WARRANTY CLAIMS RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES 
THAT IT IS RECEIVERS SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD 
PARTY ALL PROPER LICENSES CONTAINED IN ECONET SOFTWARE.

ECONET SHALL NOT BE RESPONSIBLE FOR ANY ECONET SOFTWARE RELEASES 
MADE TO RECEIVERS SPECIFICATION OR CONFORMING TO A PARTICULAR 
STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND 
ECONET'S ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE ECONET 
SOFTWARE RELEASED HEREUNDER SHALL BE, AT ECONET'S SOLE OPTION, TO 
REVISE OR REPLACE THE ECONET SOFTWARE AT ISSUE OR REFUND ANY SOFTWARE 
LICENSE FEES OR SERVICE CHARGES PAID BY RECEIVER TO ECONET FOR SUCH 
ECONET SOFTWARE.
***************************************************************/

/************************************************************************
*                  I N C L U D E S
*************************************************************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <net/if.h>

#include "omci_adpt_common.h"
#include "omci_adpt_general.h"
#include "omci_me.h"
#include "blapi_traffic.h"
#include "blapi_system_bsp.h"

#include "omci_adpt_voip.h"

#include <trx.h>

/************************************************************************
*                  D E F I N E S   &   C O N S T A N T S
*************************************************************************
*/


/************************************************************************
*                  M A C R O S
*************************************************************************
*/    

#define OMCI_MAX_LENS		(sizeof(omciGenericPayload_t))
#define OMCI_MAX_MAP_NUM    512
#define PPTP_UNI_NO_LOOPBACK_STATUS 0
#define ME65528_NO_LOOPBACK_STATUS 0
#define PPTP_UNI_PORT_ID_MASK 0xFF
#define OMCI_DEFAULT_TX_POWER_UPPER_THLD ((omci_onu_cap_g.linkMode == OMCI_LINK_MODE_GPON) ? 4 : 7)
#define OMCI_DEFAULT_TX_POWER_LOWER_THLD ((omci_onu_cap_g.linkMode == OMCI_LINK_MODE_GPON) ? 1 : 2)


#define OMCI_EVENT_INDEX_PATH   "/tmp/eventIndex.txt"
#define ARM_SECURE_BOOT_LEN   0x2000

#define eth_hsgmii	8
#define pcie1_hsgmii	7
#define pcie0_hsgmii	6
#define usb_hsgmii	5

/************************************************************************
*                  D A T A     T Y P E S
*************************************************************************
*/

typedef struct GNU_PACKED classIdHasWritalbeTableAttr_s
{
    union 
    {
    	omci_vlan_tag_ext_op_ptr ext_vlan;
    	omci_mac_br_port_filter_ptr mbpf;
    	omci_enhanced_security_ctrl_ptr enhance_sec;
    	omci_ctc_ext_multicast_op_profile_ptr ctcMulticastProf;
    	omci_multicast_op_profile_ptr multicastProf;
    	omci_multicast_subs_cfg_info_ptr multicastSubsCfgInfo;
    	omci_sip_agent_cfg_ptr sipAgentCfg;
    	omci_mc_gem_interwork_tp_ptr gemInterTP;
    	omci_voice_srv_prof_ptr voiceSrvProf;
    	omci_net_dial_plan_tab_ptr netDialPlan;
	};
}classIdHasWritalbeTableAttr_t;


typedef struct testThreadPara_s{
	management_entry_ptr me_entry;
	omci_me_info_ptr me_info;
}testThreadPara_t;

typedef enum {
	ADMIN_UNLOCK = 0,
	ADMIN_LOCKED,
	ADMIN_ERROR,
}retVal_t;

/************************************************************************
*                  E X T E R N A L     D A T A   D E C L A R A T I O N S
*************************************************************************
*/

extern uint8_t AuthStatusFlag;
extern uint8_t extendOmciFlag; //0: not support extend omci  1:support extend omci  default  value is 0
extern int setQueueMapTimer;
extern int recfgTimerId;
extern int tmrIdSecMiss;
extern int ipOptionId[MAX_IPHOST_WAN_NUM];
extern int tmrIdImage;
extern int commitWanTimer;
extern mb_uni_ani_port_t ani_uni_port[MAX_GEM_PORT_NUM];
extern mb_all_gemport_t ani_gemport[MAX_GEM_PORT_NUM];
uint8_t xsi_lanport_info_covert(uint8_t port);


/************************************************************************
*                  F U N C T I O N   D E C L A R A T I O N S
*************************************************************************
*/

static int omci_adpt_commit_node_list_destory(void);
static int omci_adpt_init_after_onu_ready(void);
int omciSaveEvent(int eventId);

/************************************************************************
*                  P U B L I C   D A T A
*************************************************************************
*/

pthread_mutex_t omciHandlePonIfc;
pthread_mutex_t omciSetMBPDevId;
pthread_mutex_t omciGetAllData;

omci_global_info_t  	omci_info_g={0};
omci_onu_capablity_t  	omci_onu_cap_g={0};
int oltTypeId = 0;
uint8_t pmIntervalTimes = 0;
omciTLSInfo_t omciTLSInfo;
OmciPktRxCnt_t OmciPktRxCnt = {0};
int olt_ctrl_qos_flag = 0;  //for HGU only, 1: qos controlled by OMCI, 0: qos controlled by web GUI
int bbf247_enable = 0;
/************************************************************************
*                  P R I V A T E   D A T A
*************************************************************************
*/

static pthread_mutex_t pmListLock;
static char omci_table_attr_buf[OMCI_MAX_TABLE_SIZE]={0};
static omci_me_info_t current_me_info = {0};

static uint8_t xponLedNeedBlink = 0;
static uint32_t g_event_mask = 0;
static uint8_t endIntervalFlag = 0;
#ifdef TCSUPPORT_OMCI_ALCATEL
static int timer_id_avc_period = 0;
#endif
static uint8_t syncTimeEnd = 0;

static int omciSocket = -1 ;
static struct sockaddr_ll socketAddr ;

#ifdef TCSUPPORT_OPENWRT
struct uci_context *uci_ctx = NULL;
struct uci_package *uci_network = NULL;
const char *config_path = DEFAULT_CONFIG_PATH;
#endif

static commitNodeList_t commitNodeList;
static pm_history_data_list_ptr pm_history_data_list = NULL;
static uint16_t stdOmciAdptIndexMap[OMCI_MAX_MAP_NUM];
static int commitNodeTimeId = INVALID_TIMERID;
static int tca_timerId = INVALID_TIMERID;
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CT_LOOPDETECT)
static int omci_lan_port_loopdetect_alarm_num = OMCI_ALARM_ID_PPTPEthernetUNI_LAN_LOOPBACK_ALARM;
#endif/*TCSUPPORT_COMPILE*/
static int omci_trap_thread_ready = 0;

enum{NORMAL_POWER = OMCI_ALARM_ID_MAX_NUM+1, UPPER_POWER, LOWER_POWER};
enum{ETH_LINK_UP, ETH_LINK_DOWN, ETH_LINK_UNKNOW};
enum{SIPUA_REG_INIT = 0,SIPUA_REG_UP, SIPUA_REG_AUTH, SIPUA_REG_TIMEOUT,SIPUA_REG_FAIL};

#define TX_POWER_DEFAULT_POLICY     0x81
#define RX_POWER_DEFAULT_POLICY     0xFF
#define RDKB_DEFAULT_POLICY         0xFE


struct omci_pm_tca_pre_info_s {
	int preRxFlag;
	int preTxFlag;
	unsigned char preStatus[MAX_ETH_PORT_NUM_ARRAY];
	unsigned char preAlarm[VOIP_MAX_CHAN_NUM];
}pmTcaPreInfo = {
	.preRxFlag = NORMAL_POWER,
	.preTxFlag = NORMAL_POWER,
	.preStatus = {ETH_LINK_UNKNOW, ETH_LINK_UNKNOW, ETH_LINK_UNKNOW, ETH_LINK_UNKNOW},
	.preAlarm = {SIPUA_REG_UP, SIPUA_REG_UP},
};

static const unsigned long crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};

#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))

#define IS_SPECIAL_OPERATION_ME    1
#define IS_GENERAL_OPERATION_ME    0



/* For all ME classes. */
static management_entry_t adpt_std_me[] = 
{
{0},/*index 0 for unsupported index, can not delete*/
{OMCI_CLASS_ID_ONU_DATA,			&omci_me_onu_data_op,			omci_attr_onu_data_op,				&omci_onu_data_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ONU_G,				&omci_me_onu_g_op,				omci_attr_onu_g_op,					&omci_onu_g_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ONU2_G,				&omci_me_onu2_g_op,				omci_attr_onu2_g_op,				&omci_onu2_g_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_SOFTWARE_IMGAE,		&omci_me_sw_image_op,			omci_attr_sw_image_op,				&omci_sw_image_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_CARDHOLDER,			&omci_me_card_holder_op,		omci_attr_card_holder_op,			&omci_card_holder_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_CIRCUIT_PACK,		&omci_me_circuit_pack_op,		omci_attr_circuit_pack_op,			&omci_circuit_pack_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ONU_POWER_SHEDDING,	&omci_me_onu_power_schedding_op,omci_attr_onu_power_schedding_op,	&omci_onu_power_schedding_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PORT_MAPPING,		&omci_me_port_mapping_pkt_op,	omci_attr_port_mapping_pkt_op,		&omci_port_mapping_pkt_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ONU_REMOTE_DEBUG,	&omci_me_onu_remote_debug_op,	omci_attr_onu_remote_debug_op,		&omci_onu_remote_debug_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ANI_G,				&omci_me_ani_g_op,				omci_attr_ani_g_op,					&omci_ani_g_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_T_CONT,				&omci_me_t_cont_op,				omci_attr_t_cont_op, 				&omci_t_cont_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_GEM_PORT_CTP,		&omci_me_gem_port_ctp_op,		omci_attr_gem_port_ctp_op,			&omci_gem_port_ctp_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PRIORITY_QUEUE, 		&omci_me_priority_queue_op,		omci_attr_priority_queue_op,		&omci_priority_queue_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_TRAFFIC_SCHEDULER,	&omci_me_traffic_scheduler_op, 	omci_attr_traffic_scheduler_op,		&omci_traffic_scheduler_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_TRAFFIC_DESCRIPTOR,	&omci_me_traffic_descriptor_op,	omci_attr_traffic_descriptor_op, 	&omci_traffic_descriptor_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_SERVICE_PROFILE,	&omci_me_mac_br_service_op,			omci_attr_mac_br_service_op,		&omci_mac_br_service_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_CON_DATA,		&omci_me_mac_br_port_cfg_op,		omci_attr_mac_br_port_cfg_op,		&omci_mac_br_port_cfg_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_CON_DATA,			&omci_me_mac_br_cfg_data_op,		omci_attr_mac_br_cfg_data_op, 		&omci_mac_br_cfg_data_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_DESIGNATION_DATA, 	&omci_me_mac_br_port_dest_op,		omci_attr_mac_br_port_dest_op,		&omci_mac_br_port_dest_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_FILTER_TABLE_DATA, 	&omci_me_mac_br_port_filter_op,		omci_attr_mac_br_port_filter_op, 	&omci_mac_br_port_filter_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_FILTER_PREASSIGN_DATA,&omci_me_mac_br_port_filter_pre_op,	omci_attr_mac_br_port_filter_pre_op,&omci_mac_br_port_filter_pre_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_TABLE_DATA, 			&omci_me_mac_br_port_br_tbl_op,		omci_attr_mac_br_port_br_tbl_op,	&omci_mac_br_port_br_tbl_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_GEM_INTERWORK_TP,			&omci_me_gem_interwork_tp_op,		omci_attr_gem_interwork_tp_op,			&omci_gem_interwork_tp_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MULTICAST_GEM_INTERWORK_TP,	&omci_me_mc_gem_interwork_tp_op,	omci_attr_mc_gem_interwork_tp_op,		&omci_mc_gem_interwork_tp_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_GAL_ETHERNET_PROFILE,		&omci_me_gal_eth_prof_op,			omci_attr_gal_eth_prof_op,				&omci_gal_eth_prof_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PPTP_ETHERNET_UNI,			&omci_me_pptp_eth_uni_op,			omci_attr_pptp_eth_uni_op,				&omci_pptp_eth_uni_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VIRTUAL_ETHERNET_INTERFACE_POINT,	&omci_me_veip_op,			omci_attr_veip_op,						&omci_veip_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MULTICAST_OPERATE_PROFILE,	&omci_me_multicast_op_prof_op,			omci_attr_multicast_op_prof_op,				&omci_multicast_op_prof_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MULTICAST_SUBSCRIBER_CFG_INFO,&omci_me_multicast_subs_cfg_info_op,	omci_attr_multicast_subs_cfg_info_op,		&omci_multicast_subs_cfg_info_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MULTICAST_SUBSCRIBER_MONITOR,	&omci_me_multicast_subs_monitor_op,		omci_attr_multicast_subs_monitor_op,		&omci_multicast_subs_monitor_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_802_1P_MAPPER, 				&omci_me_802_1p_map_service_op,	omci_attr_802_1p_map_service_op,	&omci_802_1p_map_service_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VLAN_TAG_FILTER_DATA,		&omci_me_vlan_filter_op,		omci_attr_vlan_filter_op,			&omci_vlan_filter_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VLAN_TAG_OPERATE, 		&omci_me_vlan_tag_op_cfg_op,	omci_attr_vlan_tag_op_cfg_op,		&omci_vlan_tag_op_cfg_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VLAN_TAG_EXTEND_OPERATE,	&omci_me_ext_vlan_tag_op,	    omci_attr_ext_vlan_tag_op,	&omci_ext_vlan_tag_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_OLT_G,                       &omci_me_olt_g_op,      omci_attr_olt_g_op,         &omci_olt_g_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_NETWORK_ADDRESS,             &omci_me_network_addr_op, omci_attr_network_addr_op, &omci_network_addr_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_AUTHENTICATION_METHOD,       &omci_me_auth_sec_method_op, omci_attr_auth_sec_method_op, &omci_auth_sec_method_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_LARGE_STRING,                &omci_me_large_string_op,   omci_attr_large_string_op,  &omci_large_string_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PROTECTION_PROFILE,          NULL,   NULL,   NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_EXTENSION_PACKAGE,           NULL,   NULL,   NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_UNI_G,                       &omci_me_uni_g_op,  omci_attr_uni_g_op,     &omci_uni_g_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_THRESHOLD_DATA1,             &omci_me_thd_data1_op,   omci_attr_thd_data1_op,   &omci_thd_data1_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_THRESHOLD_DATA2,             &omci_me_thd_data2_op,   omci_attr_thd_data2_op,   &omci_thd_data2_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_THRESHOLD_DATA_64_BIT,       &omci_me_thd_data_64bit_op,   omci_attr_thd_data_64bit_op,   &omci_thd_data_64bit_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PROTECTION_DATA,             NULL,   NULL,   NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_OMCI,                        &omci_me_omci_op,   omci_attr_omci_op,  &omci_omci_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MANAGED_ENTITY,              &omci_me_managed_entity_op,     omci_attr_managed_entity_op,    &omci_managed_entity_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ATTRIBUTE    ,               &omci_me_attribute_op,      omci_attr_attribute_op,         &omci_attribute_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_OCTET_STRING,                &omci_me_octet_string_op,   omci_attr_octet_string_op,      &omci_octet_string_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_GENERAL_BUFFER,              &omci_me_general_purpose_buf_op,    omci_attr_general_purpose_buf_op,   &omci_general_purpose_buf_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_FILE_TRANSFER_CONTROLLER,    &omci_me_file_transfer_ctrl_op,     omci_attr_file_transfer_ctrl_op,    &omci_file_transfer_ctrl_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_GENERIC_STATUS,              &omci_me_generic_stat_portal_op,    omci_attr_generic_stat_portal_op,   &omci_generic_stat_portal_attr, IS_GENERAL_OPERATION_ME},
#if defined(TCSUPPORT_SNMP)&&(!defined(BSP_BUILD))
{OMCI_CLASS_ID_SNMP_CONFIG_DATA,            &omci_me_snmp_cfg_data_op,      omci_attr_snmp_cfg_data_op,         &omci_snmp_cfg_data_attr, IS_GENERAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_TR069_MANAGE_SERVER,         &omci_me_tr69_manage_srv_op,    omci_attr_tr69_manage_srv_op,       &omci_tr69_manage_srv_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ONU_E ,                      NULL,   NULL,   NULL},
{OMCI_CLASS_ID_ONU_DYNAMIC_POWER ,          NULL,   NULL,   NULL},
{OMCI_CLASS_ID_ENHANCED_SECURITY_CONTROL,   &omci_me_enhanced_security_ctrl_op, omci_attr_enhanced_security_ctrl_op, &omci_enhanced_security_ctrl_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_DOT1_RATE_LIMITER,           &omci_me_dot1_rate_limit_op,    omci_attr_dot1_rate_limit_op,   &omci_dot1_rate_limit_attr, IS_GENERAL_OPERATION_ME},
#ifdef TCSUPPORT_OMCI_DOT1AG
{OMCI_CLASS_ID_DOT1AG_MAINTENANCE_DOMAIN,   &omci_me_dot1ag_maint_domain_op,    omci_attr_dot1ag_maint_domain_op, &omci_dot1ag_maint_domain_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_DOT1AG_MAINTENANCE_ASSOCIATION,  &omci_me_dot1ag_maint_associat_op,  omci_attr_dot1ag_maint_associat_op, &omci_dot1ag_maint_associat_attr, IS_GENERAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_ICMPV6,      &omci_me_mac_br_port_icmpv6_proc_pre_tbl_op, omci_attr_mac_br_port_icmpv6_proc_pre_tbl_op, &omci_mac_br_port_icmpv6_proc_pre_tbl_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_IP_HOST_CONFIG_DATA,         &omci_me_ip_host_cfg_op,    omci_attr_ip_host_cfg_op, &omci_ip_host_cfg_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_TCP_UDP_CFGDATA,             &omci_me_tcp_udp_config_op, omci_attr_tcp_udp_config_op, &omci_tcp_udp_config_attr, IS_GENERAL_OPERATION_ME},
#ifdef TCSUPPORT_VOIP
{OMCI_CLASS_ID_SIP_USER_DATA,               &omci_me_sip_user_data_op,  omci_attr_sip_user_data_op,  &omci_sip_user_data_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VOIP_MEDIA_PROFILE,          &omci_me_voip_media_prof_op,  omci_attr_voip_media_prof_op, &omci_voip_media_prof_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VOIP_VOICE_CTP,              &omci_me_voip_voice_ctp_op, omci_attr_voip_voice_ctp_op, &omci_voip_voice_ctp_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_MGC_CFG_DATA,                &omci_me_mgc_cfg_data_op,   omci_attr_mgc_cfg_data_op,  &omci_mgc_cfg_data_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VOIP_CFG_DATA,               &omci_me_voip_cfg_data_op,  omci_attr_voip_cfg_data_op, &omci_voip_cfg_data_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_NETWORK_DIAL_PLAN_TBL,       &omci_me_net_dial_plan_tab_op, omci_attr_net_dial_plan_tab_op, &omci_net_dial_plan_tab_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RTP_PROFILE_DATA,                      &omci_me_rtp_prof_op,   omci_attr_rtp_prof_op,  &omci_rtp_prof_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VOICE_SERVICE_PROFILE,                 &omci_me_voice_srv_prof_op, omci_attr_voice_srv_prof_op,    &omci_voice_srv_prof_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VOIP_APP_SVC_PROFILE,        &omci_me_voip_app_srv_prof_op, omci_attr_voip_app_srv_prof_op,  &omci_voip_app_srv_prof_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_VOIP_LINE_STATUS,            &omci_me_voip_line_status_op,   omci_attr_voip_line_status_op,  &omci_voip_line_status_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PPTP_POTS_UNI,            &omci_me_pptp_pots_uni_op,      omci_attr_pptp_pots_uni_op,     &omci_pptp_pots_uni_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_SIP_AGENT_CONFIG_DATA,       &omci_me_sip_agent_cfg_op,      omci_attr_sip_agent_cfg_op,     &omci_sip_agent_cfg_attr, IS_GENERAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_PPTP_VIDEO_UNI,          &omci_me_pptp_video_uni_op,      omci_attr_pptp_video_uni_op,     &omci_pptp_video_uni_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PPTP_VIDEO_ANI,          &omci_me_pptp_video_ani_op,      omci_attr_pptp_video_ani_op,     &omci_pptp_video_ani_attr, IS_GENERAL_OPERATION_ME},
/*PM ME*/
{OMCI_CLASS_ID_FEC_PM_DATA,                 &omci_me_fec_pm_hist_op,        omci_attr_fec_pm_hist_op,   &omci_fec_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PMHD,          &omci_me_mac_br_pm_his_op,          omci_attr_mac_br_pm_his_op,         &omci_mac_br_pm_his_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_MAC_BRIDGE_PORT_PMHD,     &omci_me_mac_br_port_pm_his_op, omci_attr_mac_br_port_pm_his_op, &omci_mac_br_port_pm_his_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_GEM_PORT_NETWORK_CTP_PM,     &omci_me_gemport_net_ctp_pm_his_op,  omci_attr_gemport_net_ctp_pm_his_op,  &omci_gemport_net_ctp_pm_his_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ENERGY_CONSUMPTION_PM,       &omci_me_energy_pm_his_op,       omci_attr_energy_pm_his_op, &omci_energy_pm_his_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_GEM_PORT_PM,                 &omci_me_gem_port_pm_op,         omci_attr_gem_port_pm_op,   &omci_gem_port_pm_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_GAL_ETHERNET_PM,             &omci_me_gal_eth_pm_hist_op,     omci_attr_gal_eth_pm_hist_op, &omci_gal_eth_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA,    &omci_me_eth_pm_his_op,          omci_attr_eth_pm_his_op,     &omci_eth_pm_his_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_2,  &omci_me_eth_pm_his_2_op,        omci_attr_eth_pm_his_2_op,   &omci_eth_pm_his_2_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_3,  &omci_me_eth_pm_his_3_op,        omci_attr_eth_pm_his_3_op,   &omci_eth_pm_his_3_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM,  &omci_me_eth_frame_ext_pm_op,    omci_attr_eth_frame_ext_pm_op, &omci_eth_frame_ext_pm_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM_64_BIT, &omci_me_eth_frame_ext_pm_64bit_op, omci_attr_eth_frame_ext_pm_64bit_op, &omci_eth_frame_ext_pm_64bit_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_IP_HOST_PM,                  &omci_me_ip_host_pm_his_op,      omci_attr_ip_host_pm_his_op,  &omci_ip_host_pm_his_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_FRAME_UP_PMHD,   &omci_me_eth_frame_pm_his_up_op,    omci_attr_eth_frame_pm_his_up_op,   &omci_eth_frame_pm_his_up_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_FRAME_DOWN_PMHD, &omci_me_eth_frame_pm_his_down_op,  omci_attr_eth_frame_pm_his_down_op, &omci_eth_frame_pm_his_down_attr, IS_SPECIAL_OPERATION_ME},
#ifdef TCSUPPORT_VOIP
{OMCI_CLASS_ID_CALL_CTRL_PM_HISTORY,                  &omci_me_call_ctl_pm_hist_op,    omci_attr_call_ctl_pm_hist_op, &omci_call_ctl_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_RTP_PM_HISTORY_DATA,         &omci_me_rtp_pm_hist_op,         omci_attr_rtp_pm_hist_op,      &omci_rtp_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_SIP_AGENT_PM_HISTORY,           &omci_me_sip_agent_pm_hist_op,   omci_attr_sip_agent_pm_hist_op, &omci_sip_agent_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_SIP_CALL_INIT_PM_HISTORY,       &omci_me_sip_call_init_pm_hist_op, omci_attr_sip_call_init_pm_hist_op, &omci_sip_call_init_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_TCP_UDP_PM,                  &omci_me_tcp_udp_pm_his_op,      omci_attr_tcp_udp_pm_his_op,   &omci_tcp_udp_config_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ENHANCED_FEC_PM_DATA,        &omci_me_enhanced_fec_pm_hist_op,   omci_attr_enhanced_fec_pm_hist_op,  &omci_enhanced_fec_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_XGPON_TC_PM,                 &omci_me_xgon_tc_pm_hist_op,   omci_attr_xgon_tc_pm_hist_op,  &omci_xgon_tc_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ENHANCED_TC_PM,              &omci_me_enhanced_tc_pm_hist_op,   omci_attr_enhanced_tc_pm_hist_op,  &omci_enhanced_tc_pm_hist_attr, IS_SPECIAL_OPERATION_ME},                        
{OMCI_CLASS_ID_XGPON_DS_MGNT_PM,            &omci_me_xgon_ds_mgnt_pm_hist_op,   omci_attr_xgon_ds_mgnt_pm_hist_op,  &omci_xgon_ds_mgnt_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_XGPON_US_MGNT_PM,            &omci_me_xgon_us_mgnt_pm_hist_op,   omci_attr_xgon_us_mgnt_pm_hist_op,  &omci_xgon_us_mgnt_pm_hist_attr, IS_SPECIAL_OPERATION_ME},
};

/*vendor ME*/
static management_entry_t adpt_vendor_me[] =
{
#ifdef TCSUPPORT_OMCI_CTC  
{OMCI_CLASS_ID_CTC_ONU_LOOP_DETECTION,   &omci_me_ctc_loop_detect_op,       omci_attr_ctc_loop_detect_op, &omci_ctc_loop_detect_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_CTC_ONU_CAPABILITY,       NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_CTC_LOID_AUTHEN,          &omci_me_ctc_loid_auth_op,       omci_attr_ctc_loid_auth_op, &omci_ctc_loid_auth_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_CTC_EXTENDED_MUTICAST_PROFILE,  &omci_me_ctc_ext_multicast_op_profile_op, omci_attr_ctc_ext_multicast_op_profile_op, &omci_ctc_ext_multicast_op_profile_attr, IS_GENERAL_OPERATION_ME},
#endif                                                                                
#ifdef TCSUPPORT_CUC                                                                  
{OMCI_CLASS_ID_CUC_ONU_CAPABILITY,        NULL, NULL, NULL},
{OMCI_CLASS_ID_ONU_OPTICAL_TRANS_INFO,    &omci_me_cuc_onu_trans_info_op, omci_attr_cuc_onu_trans_info_op, &omci_cuc_onu_trans_info_attr,IS_GENERAL_OPERATION_ME},
#endif                                                                               
#ifdef TCSUPPORT_OMCI_ALCATEL
#ifdef TCSUPPORT_VOIP
{OMCI_CLASS_ID_VOIP_CALL_STATISTICS,      &omci_me_alcatel_voip_call_statistics_op, omci_attr_alcatel_voip_call_statistics_op, &omci_alcatel_voip_call_statistics_attr, IS_GENERAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_CLOCK_DATA_SET,            &omci_me_alcatel_clock_data_set_op,   omci_attr_alcatel_clock_data_set_op,    &omci_alcatel_clock_data_set_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PTP_MASTER_CONFIG_DATA_PROFILE,     &omci_me_alcatel_ptp_mst_cfg_op, omci_attr_alcatel_ptp_mst_cfg_op,   &omci_alcatel_ptp_mst_cfg_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_PTP_Port,                  &omci_me_alcatel_ptp_port_op,     omci_attr_alcatel_ptp_port_op,  &omci_alcatel_ptp_port_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_TOTAL_GEM_PORT_PM,         &omci_me_alcatel_total_gemport_pm_op, omci_attr_alcatel_total_gemport_pm_op,  &omci_alcatel_total_gemport_pm_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_ETHERNET_TRAFFIC_PM,       &omci_me_alcatel_eth_traffic_pm_op,   omci_attr_alcatel_eth_traffic_pm_op,    &omci_alcatel_eth_traffic_pm_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_VLAN_TAG_DOWNSTREAM_EGRESS_BEHAVIOR_SUPPLEMENTAL1,     &omci_me_alcatel_vlan_tag_down_supply_1_op,   omci_attr_alcatel_vlan_tag_down_supply_1_op, &omci_alcatel_vlan_tag_down_supply_1_attr, IS_GENERAL_OPERATION_ME},
#if defined (TCSUPPORT_UPSTREAM_VLAN_POLICER)
{OMCI_CLASS_ID_VLAN_TAG_UPSTREAM_POLICER, &omci_me_alcatel_vlan_tag_up_policy_op,   omci_attr_alcatel_vlan_tag_up_policy_op,    &omci_alcatel_vlan_tag_up_policy_attr, IS_GENERAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_ONT_OPTICAL_SUPERVISION_STATUS,   &omci_me_alcatel_ont_optical_Status_op, omci_attr_alcatel_ont_optical_Status_op,   &omci_alcatel_ont_optical_Status_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_UNI_SUPPLEMENTAL_1_V2,            &omci_me_alcatel_uni_supply_1v2_op,    omci_attr_alcatel_uni_supply_1v2_op,    &omci_alcatel_uni_supply_1v2_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_ONT_GENERIC_V2,                   &omci_me_alcatel_ont_generic_v2_op,    omci_attr_alcatel_ont_generic_v2_op,    &omci_alcatel_ont_generic_v2_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_GEMPORT_PROTOCOL_MONITORING_HISTORY_DATA_PART_2,		&omci_me_alcatel_gemport_protocol_pm_op,    omci_attr_alcatel_gemport_protocol_pm_op,   &omci_alcatel_gemport_protocol_pm_attr, IS_SPECIAL_OPERATION_ME},	
#endif
{OMCI_CLASS_ID_RESERVED_247_ME,        &omci_me_247_op, omci_attr_247_op, &omci_me247_attr, IS_GENERAL_OPERATION_ME},
#ifdef TCSUPPORT_VNPTT
{OMCI_CLASS_ID_RESERVED_250_ME,        NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_347_ME,        NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
#else
{OMCI_CLASS_ID_RESERVED_250_ME, &omci_me_PPPoE_wan_config_op,omci_attr_PPPoE_wan_config_op,&omci_PPPoE_wan_cfg_attr_attr, IS_GENERAL_OPERATION_ME},
#endif                                                                                
{OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_4,	&omci_me_eth_pm_his_4_op,		 omci_attr_eth_pm_his_4_op,   &omci_eth_pm_his_4_attr, IS_SPECIAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_351_PM,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},

#ifdef TCSUPPORT_PON_ROSTELECOM
{OMCI_CLASS_ID_HUAWEI_CONFIG_UPLOAD,	NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
#endif

#ifdef TCSUPPORT_HUAWEI_OLT_VENDOR_SPECIFIC_ME
{OMCI_CLASS_ID_RESERVED_350_ME,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_352_ME,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
#ifndef TCSUPPORT_PON_ROSTELECOM
{OMCI_CLASS_ID_RESERVED_353_ME,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
#endif
{OMCI_CLASS_ID_RESERVED_367_ME,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_373_ME,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
#ifdef TCSUPPORT_HUAWEI_OLT_VENDOR_SPECIFIC_ME_FOR_INA
{OMCI_CLASS_ID_RESERVED_370_ME,         NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_65408_ME,       &omci_me_65408_op, omci_attr_65408_op, &omci_me65408_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_65414_ME,       NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_65415_ME,		&omci_me_65415_op, omci_attr_65415_op, &omci_me65415_attr, IS_GENERAL_OPERATION_ME},
{OMCI_CLASS_ID_RESERVED_65425_ME,       NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
#endif
#endif
{OMCI_CLASS_ID_RESERVED_65427_ME,       NULL, NULL, NULL, IS_GENERAL_OPERATION_ME},
};

/************************************************************************
*                  F U N C T I O N   D E F I N I T I O N S
*************************************************************************
*/

static int omci_me_clear_xpon_rule(void)
{
	int ret = 0, i = 0;
	omci_adpt_commit_node_list_destory();
	/*clean gpon mapping rule*/
	omciEmptyQueueMappingRule();
	/*clear vlan rule*/
	pon_clean_all_vlan_rule();
	setExtVlanOpTBLDefaultRule();	
	/*clear vlan filter rule*/
	cleanAllGponVlanFilterRule();
	for(i = 1; i<= MAX_ETH_PORT_NUM; i++){
		pon_enable_default_vlan_rule(i+PONVLAN_PORT_OFFSET_ETH);
	} 
#ifdef TCSUPPORT_PON_MAC_FILTER
	/*clear mac filter rule*/
	pon_clean_all_mac_filter_rule();
#endif
#ifdef TCSUPPORT_XPON_IGMP
	/*clear igmp rule*/
	igmpONUSetGponMode();
#endif
	/*clear PM list*/
    omci_pm_clear_list_for_mibrest();
	/*clear user isolation rule*/	
	if(SFU == omci_info_g.onuType)
		pon_clean_all_user_group();
	/*reset hwnat rule*/
	pon_clean_hwnat();

	/*clear GPON Flow list*/
	omci_flow_clean_all_rule();

	/*clear drop precedunce */ 
	omci_clear_drop_preceduce_color_mark();

	return ret;
}

static int omci_me_mib_reset_op(void)
{
	//reset voip Config
	if(omci_voip_set_config_method_used(OMCI_VOIP_CFG_DATA_CFG_METHOD_NOT_USED) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: reset voipConfig  fail\n",__FUNCTION__,__LINE__);
	}
	
	memset(&ani_uni_port,0,sizeof(ani_uni_port));
	memset(&ani_gemport,0,sizeof(ani_gemport));
	return omci_me_clear_xpon_rule();
}

static int omci_me_sync_time_op()
{   
    pmIntervalTimes = 0;
    omci_lib_adpt_update_pm_history_data();
    syncTimeEnd = 1;    

    return 0;
}

/******************************************************************************
******************************************************************************/

attribute_func_t generalAttrFunc = {
	NULL,
	NULL
};


omci_me_info_t getCurrentMeInfo(void){
	return current_me_info;
}

management_entry_t * getAdptMeEntryByClassId(uint16_t classId)
{
    uint16_t me_index = 0;
    int i = 0;
    if( (classId >= 240 && classId <= 255) 
        || (classId >= 350 && classId <= 399)
        || (classId >= 65280 && classId <= 65535) 
        || classId >= OMCI_MAX_MAP_NUM)
    {
        for(i = 0; i < sizeof(adpt_vendor_me)/sizeof(management_entry_t); i++)
        {
            if(adpt_vendor_me[i].omciMeClassId == classId)
                return &adpt_vendor_me[i];
        }
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]unkown reserved ME(%d) .\n",__FUNCTION__,__LINE__, classId);
        return NULL;
    }

    me_index = stdOmciAdptIndexMap[classId];
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: classId = %d, me_index = %d.\n",__FUNCTION__,__LINE__,classId, me_index);

    if(me_index == 0){
        for(i = 0; i < sizeof(adpt_vendor_me)/sizeof(management_entry_t); i++)
        {
            if(adpt_vendor_me[i].omciMeClassId == classId)
                return &adpt_vendor_me[i];
        }
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]unkown Standard ME(%d) .\n",__FUNCTION__,__LINE__, classId);
        return NULL;
    }else
        return &adpt_std_me[me_index];
}


/*get the table attribute data of the me,and we can only get one of it*/
int omci_attr_get_one_table_attr_by_mask( omci_me_info_ptr me_info)
{
	management_entry_t *adpt_me_entry = NULL;
	omci_attr_dscp_ptr omci_attr = NULL;
	uint16_t table_mask = 0;
	int i = 0;

	if(NULL == me_info){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	adpt_me_entry = getAdptMeEntryByClassId(me_info->class_id);
	if(adpt_me_entry == NULL)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]the classId(%d) can not get the entry.\n",__FUNCTION__,__LINE__, me_info->class_id);
		return -1;
	}
	for( i = 1; i <= 16; i++){
		omci_attr = adpt_me_entry->omci_attr_dscp_list + i;
		if((NULL == omci_attr)||(255 == omci_attr->attriIndex)){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: attribute end.\n",__FUNCTION__,__LINE__);
			break;
		}
		if(me_info->mask & (0x8000 >> (i-1))){
			if(ATTR_FORMAT_TABLE == omci_attr->format){/* Table Attribute */
				table_mask = 0x8000 >> (i-1);
				break;
			}
		}
	}
	if(0 == table_mask){
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Attribute mask error,without table attr mask bit.\n",__FUNCTION__,__LINE__);
		return -1;
	}else if(me_info->mask & ~table_mask){
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Attribute mask error,more than one table attr mask bit.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	if(adpt_me_entry->attr != NULL && adpt_me_entry->attr->attrData!= NULL)
	{	
		//memset(adpt_me_entry->attr->attrData,0,adpt_me_entry->attr->attrLen);
		me_info->attributes = adpt_me_entry->attr->attrData;
		me_info->attr_len = adpt_me_entry->attr->attrLen;
		memset(omci_table_attr_buf,0,OMCI_MAX_TABLE_SIZE);

		if(omci_get_all_attrs_by_instid(me_info, omci_table_attr_buf,OMCI_MAX_TABLE_SIZE) == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]get attribute failed.class_id:%d, inst_id:%d\n",
				__FUNCTION__,__LINE__, me_info->class_id, me_info->inst_id);
			return -1;
		}
	}else{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]adpt_me_entry->attr or adpt_me_entry->attr->attrData is NULL.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	return 0;
}

/*get the latest data of the ME,if the current ME is performing right now,as the OMCI_frame udpate the database only after 
the Adapeter execution return,so we should be more attetion of it.
otherwise,we can get the data from the omci_frame directly*/
int omci_attr_get_all_data_except_table_attr( omci_me_info_ptr me_info)
{
    management_entry_t *adpt_me_entry = NULL;
	if(NULL == me_info){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	if(me_info->class_id == current_me_info.class_id
		&&(me_info->inst_id == current_me_info.inst_id)
		&&(MT_OMCI_MSG_TYPE_GET != current_me_info.msg_type)
		&&(MT_OMCI_MSG_TYPE_GET_CURR_DATA != current_me_info.msg_type)
		&&(MT_OMCI_MSG_TYPE_DELETE != current_me_info.msg_type)
		&&(MT_OMCI_MSG_TYPE_TEST != current_me_info.msg_type))/* Get Current ME Attribtes */
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]the msg_type is %d.\n",__FUNCTION__,__LINE__,current_me_info.msg_type);
		memcpy(me_info,&current_me_info,sizeof(omci_me_info_t));
		return 0;
	}

	adpt_me_entry = getAdptMeEntryByClassId(me_info->class_id);
	if(adpt_me_entry == NULL)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]the classId(%d) can not get the entry.\n",__FUNCTION__,__LINE__, me_info->class_id);
		return -1;
	}
	if(adpt_me_entry->attr != NULL && adpt_me_entry->attr->attrData	!= NULL)
	{	
		memset(adpt_me_entry->attr->attrData,0,adpt_me_entry->attr->attrLen);
		me_info->attributes = adpt_me_entry->attr->attrData;
		me_info->attr_len = adpt_me_entry->attr->attrLen;
		//memset(omci_table_attr_buf,0,OMCI_MAX_TABLE_SIZE);
		if(omci_get_all_attrs_by_instid(me_info, NULL,OMCI_MAX_TABLE_SIZE) == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]: get attribute failed, class_id:%d, inst_id:%d\n",
				__FUNCTION__,__LINE__, me_info->class_id, me_info->inst_id);
			return -1;
		}
	}else{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: attrData is NULL!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0\n",__FUNCTION__,__LINE__);
	return 0;
}

/*get the history data of the ME,in simple terms:the data stored in OMCI_frame database*/
int omci_attr_get_old_data_except_table_attr( omci_me_info_ptr me_info)
{
	management_entry_t *adpt_me_entry = NULL;

	if(NULL == me_info){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	adpt_me_entry = getAdptMeEntryByClassId(me_info->class_id);
	if(adpt_me_entry == NULL)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]the classId(%d) can not get the entry.\n",__FUNCTION__,__LINE__, me_info->class_id);
		return -1;
	}
	if(adpt_me_entry->attr != NULL && adpt_me_entry->attr->attrData!= NULL)
	{	
		memset(adpt_me_entry->attr->attrData,0,adpt_me_entry->attr->attrLen);
		me_info->attributes = adpt_me_entry->attr->attrData;
		me_info->attr_len = adpt_me_entry->attr->attrLen;
		//memset(omci_table_attr_buf,0,OMCI_MAX_TABLE_SIZE);
		
		if(omci_get_all_attrs_by_instid(me_info, NULL,OMCI_MAX_TABLE_SIZE) == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]get attribute failed.class_id:%d, inst_id:%d\n",
				__FUNCTION__,__LINE__, me_info->class_id, me_info->inst_id);
			return -1;
		}
	}else{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]adpt_me_entry->attr or adpt_me_entry->attr->attrData is NULL.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	return 0;
}

static retVal_t omci_me_admin_state_op(omci_me_info_ptr me_info)
{
	uint8_t admin_state = 0;
	uint16_t admin_attr_mask = 0;/*Declare the attributes, which administrative state can't lock!*/

	if((NULL == me_info)||(NULL == me_info->attributes)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return ADMIN_ERROR;
	}
	switch(me_info->class_id){
		case OMCI_CLASS_ID_ONU_G:
			admin_state = ((omci_onu_g_ptr)(me_info->attributes))->adminState;
			admin_attr_mask = 0x0200; /*Attribute 7*/
			break;
		case OMCI_CLASS_ID_CIRCUIT_PACK:
			admin_state = ((omci_circuit_pack_ptr)(me_info->attributes))->adminState;
			admin_attr_mask = 0x0400; /*Attribute 6*/
			break;
		case OMCI_CLASS_ID_PPTP_ETHERNET_UNI:
			admin_state = ((omci_pptp_eth_uni_ptr)(me_info->attributes))->adminState;
			admin_attr_mask = 0x0800; /*Attribute 5*/
			break;
		/*case OMCI_CLASS_ID_VIRTUAL_ETHERNET_INTERFACE_POINT:
			admin_state = ((omci_veip_ptr)(me_info->attributes))->adminState;
			admin_attr_mask = 0x8000; *//*Attribute 1*//*
			break;*/
		case OMCI_CLASS_ID_UNI_G:
			admin_state = ((omci_uni_g_ptr)(me_info->attributes))->adminState;
			admin_attr_mask = 0x4000; /*Attribute 2*/
			break;
		default:
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] class:%d,instance:%d,without administrative attribute.\n",
				__FUNCTION__,__LINE__,me_info->class_id,me_info->inst_id);
			return ADMIN_UNLOCK;
	}
	if(0 == admin_state){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] class:%d,instance:%d,administrative unlock.\n",
			__FUNCTION__,__LINE__,me_info->class_id,me_info->inst_id);
		return ADMIN_UNLOCK;
	}
	if(me_info->mask & admin_attr_mask){
		me_info->mask &= (~admin_attr_mask); /*clear the original mask, as execute mask for return */
	}
	return ADMIN_LOCKED;
}


/* return 0 as success, return -1 as fail. */
int omci_me_general_create_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{	
	int ret=0;
	ret =  omci_me_general_set_op(me_entry, me_info);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return ret=%d.\n",__FUNCTION__,__LINE__,ret);
	return ret;
}

int omci_me_general_delete_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: Enter, return 0\n",__FUNCTION__,__LINE__);
	return 0;
}

int splitExtendOmciTableAttr(omci_me_info_ptr me_info, uint16_t currentEntryNum, uint16_t attrLen, uint8_t attrIdx)
{
    uint16_t classId = 0;
    int totalEntrySize = 0;
    classIdHasWritalbeTableAttr_t ptr;
    uint16_t tableLen = 0;
    char *tableContPtr = NULL;
    uint8_t *tmp = NULL;

    if(me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: Enter\n",__FUNCTION__,__LINE__);
        return -1;
    }

    memset(&ptr, 0, sizeof(classIdHasWritalbeTableAttr_t));

    classId= me_info->class_id;
    
    switch(classId)
    {
        case OMCI_CLASS_ID_VLAN_TAG_EXTEND_OPERATE:
            ptr.ext_vlan = (omci_vlan_tag_ext_op_ptr)(me_info->attributes);
            tableContPtr = ptr.ext_vlan->vlanTaggingOp.buf;
            tableLen = ptr.ext_vlan->vlanTaggingOp.len;
            break;
        case OMCI_CLASS_ID_MAC_BRIDGE_PORT_FILTER_TABLE_DATA:
            ptr.mbpf = (omci_mac_br_port_filter_ptr)(me_info->attributes);
            tableContPtr = ptr.mbpf->macFilterOp.buf;
            tableLen = ptr.mbpf->macFilterOp.len;
            break;
        case OMCI_CLASS_ID_ENHANCED_SECURITY_CONTROL:
            ptr.enhance_sec = (omci_enhanced_security_ctrl_ptr)(me_info->attributes);
            if(attrIdx == 11)
            {
                tableContPtr = ptr.enhance_sec->broadcastKeyTable.buf;
                tableLen = ptr.enhance_sec->broadcastKeyTable.len;
            }
            break;
        case OMCI_CLASS_ID_CTC_EXTENDED_MUTICAST_PROFILE:
            ptr.ctcMulticastProf = (omci_ctc_ext_multicast_op_profile_ptr)(me_info->attributes);
            if(attrIdx == 7)
            {
                tableContPtr = ptr.ctcMulticastProf->dynAccessCtrlListTable.buf;
                tableLen = ptr.ctcMulticastProf->dynAccessCtrlListTable.len;
            }
            if(attrIdx == 8)
            {
                tableContPtr = ptr.ctcMulticastProf->staticAccessCtrlListTable.buf;
                tableLen = ptr.ctcMulticastProf->staticAccessCtrlListTable.len;
            }
            break;
        case OMCI_CLASS_ID_MULTICAST_OPERATE_PROFILE:
            ptr.multicastProf = (omci_multicast_op_profile_ptr)(me_info->attributes);
            if(attrIdx == 7)
            {
                tableContPtr = ptr.multicastProf->dynAccessCtrlListTable.buf;
                tableLen = ptr.multicastProf->dynAccessCtrlListTable.len;
            }
            if(attrIdx == 8)
            {
                tableContPtr = ptr.multicastProf->staticAccessCtrlListTable.buf;
                tableLen = ptr.multicastProf->staticAccessCtrlListTable.len;
            }
            break;
        case OMCI_CLASS_ID_MULTICAST_SUBSCRIBER_CFG_INFO:
            ptr.multicastSubsCfgInfo = (omci_multicast_subs_cfg_info_ptr)(me_info->attributes);
            if(attrIdx == 6)
            {
                tableContPtr = ptr.multicastSubsCfgInfo->multiSrvPackTable.buf;
                tableLen = ptr.multicastSubsCfgInfo->multiSrvPackTable.len;
            }
            if(attrIdx == 7)
            {
                tableContPtr = ptr.multicastSubsCfgInfo->allowPreGroupTable.buf;
                tableLen = ptr.multicastSubsCfgInfo->allowPreGroupTable.len;
            }
            break;        
        case OMCI_CLASS_ID_MULTICAST_GEM_INTERWORK_TP:
            ptr.gemInterTP = (omci_mc_gem_interwork_tp_ptr)(me_info->attributes);
            if(attrIdx == 9)
            {
                tableContPtr = ptr.gemInterTP->IPv4McAddrTbl.buf;
                tableLen = ptr.gemInterTP->IPv4McAddrTbl.len;
            }
            if(attrIdx == 10)
            {
                tableContPtr = ptr.gemInterTP->IPv6McAddrTbl.buf;
                tableLen = ptr.gemInterTP->IPv6McAddrTbl.len;
            }
            break;
        case OMCI_CLASS_ID_SIP_AGENT_CONFIG_DATA:
            ptr.sipAgentCfg = (omci_sip_agent_cfg_ptr)(me_info->attributes);
            if(attrIdx == 12)
            {
                tableContPtr = ptr.sipAgentCfg->sipRespTab.buf;
                tableLen = ptr.sipAgentCfg->sipRespTab.len;
            }
            break;
        case OMCI_CLASS_ID_VOICE_SERVICE_PROFILE:
            ptr.voiceSrvProf = (omci_voice_srv_prof_ptr)(me_info->attributes);
            if(attrIdx == 10)
            {
                tableContPtr = ptr.voiceSrvProf->tonePatternTab.buf;
                tableLen = ptr.voiceSrvProf->tonePatternTab.len;
            }
            if(attrIdx == 11)
            {
                tableContPtr = ptr.voiceSrvProf->toneEventTab.buf;
                tableLen = ptr.voiceSrvProf->toneEventTab.len;
            }
            if(attrIdx == 12)
            {
                tableContPtr = ptr.voiceSrvProf->ringingPatternTab.buf;
                tableLen = ptr.voiceSrvProf->ringingPatternTab.len;
            }
            if(attrIdx == 13)
            {
                tableContPtr = ptr.voiceSrvProf->ringingEventTab.buf;
                tableLen = ptr.voiceSrvProf->ringingEventTab.len;
            }
            break;
        case OMCI_CLASS_ID_NETWORK_DIAL_PLAN_TBL:
            ptr.netDialPlan = (omci_net_dial_plan_tab_ptr)(me_info->attributes);
            if(attrIdx == 6)
            {
                tableContPtr = ptr.netDialPlan->dialPlanTab.buf;
                tableLen = ptr.netDialPlan->dialPlanTab.len;
            }
            break;
        default:
            if(currentEntryNum == 0)
            {
                omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]: unknown classId(%d), excute first Table Entry\n",__FUNCTION__,__LINE__, classId);
                return 0;
            }
            else
            {
                omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]: unknown classId(%d), EXIT Loop( more than one Table Entry)\n",__FUNCTION__,__LINE__, classId);
                return -1;
            }
    }
    totalEntrySize = tableLen/attrLen;
    if(totalEntrySize > currentEntryNum)
    {
        if(currentEntryNum > 0)
        {
            if(tableContPtr == NULL)
            {
                omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]: classId(%d) attrIdx(%d) tableContPtr pointer is NULL\n",__FUNCTION__,__LINE__, classId, attrIdx);
                return -1;
            }
            tmp = calloc(1, attrLen);
            if(tmp == NULL)
            {
                omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]: classId(%d) attrIdx(%d) calloc failed\n",__FUNCTION__,__LINE__, classId, attrIdx);
                return -1;
            }
            memcpy(tmp, tableContPtr, attrLen);
            memmove(tableContPtr, tableContPtr+attrLen, tableLen - attrLen);
            memcpy(tableContPtr+tableLen - attrLen, tmp, attrLen);
            free(tmp);
        }
        return 0;
    }
    return -1;
}


int omci_me_general_set_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	uint16_t class_id = 0, inst_id = 0, cur_mask = 0, set_mask = 0;
	omci_attr_dscp_ptr omci_attr = NULL;
	int i = 0, ret = 0 ;
	retVal_t admin_ret = 0;
	int tableSplitRet = 0;
	uint16_t multiEntryNum = 0;

    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: Enter\n",__FUNCTION__,__LINE__);
	if((NULL == me_entry)||(NULL == me_info)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	admin_ret = omci_me_admin_state_op(me_info);
	if(ADMIN_ERROR == admin_ret){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_me_admin_state_op error.\n",__FUNCTION__,__LINE__);
		return -1;
	}else if(ADMIN_LOCKED == admin_ret){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] class:%d,instance:%d,administrative locked.\n",
			__FUNCTION__,__LINE__,me_info->class_id,me_info->inst_id);
		return 0;
	}
	class_id = me_info->class_id;
	inst_id = me_info->inst_id;
	set_mask = me_info->mask;
	me_info->opt_mask = 0;
		
	for(i = 0; i < 16; i++){
		cur_mask = 1 << (15-i);
		omci_attr = me_entry->omci_attr_dscp_list+(i+1);
		if((NULL == omci_attr)||(255 == omci_attr->attriIndex)){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: attribute end.\n",__FUNCTION__,__LINE__);
			break;
		}
		if(cur_mask & set_mask){
			if(ATTR_UNSUPPORT == omci_attr->support){/* NOT Support */
				me_info->opt_mask |= cur_mask; /* set the optional mask */
			}else if((NULL != omci_attr->func) && (NULL != omci_attr->func->set_val)){
				if(omci_attr->format == ATTR_FORMAT_TABLE)
			    {
			        multiEntryNum = 0;
			        while(ret == 0 &&  tableSplitRet != -1)
			        {			            
			            omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] current table entry number = %d\n",__FUNCTION__,__LINE__, multiEntryNum); 
			            tableSplitRet |= splitExtendOmciTableAttr(me_info, multiEntryNum , omci_attr->attriLen, omci_attr->attriIndex);
			            if(tableSplitRet == 0)
			                ret |= omci_attr->func->set_val(me_info, omci_attr);
			            else
			                omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]current table entry number = %d Split Fail\n",__FUNCTION__,__LINE__, multiEntryNum);
			            multiEntryNum++;
			        }
			    }
			    else
				    ret = omci_attr->func->set_val(me_info, omci_attr);
				if(ret == 0){
					me_info->mask &= (~cur_mask);  /*clear the original mask, as execute mask for return */
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]set attribute failed! class_id:%d, inst_id:%d, attr_idx:%d\n",
						__FUNCTION__,__LINE__, class_id, inst_id, (i+1));
				}
			}else{ /* Adapter do nothing for this attribute action*/
				ret = 0;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]Nothing to do in adapter. class_id:%d, inst_id:%d, attr_idx:%d\n",
					__FUNCTION__,__LINE__, class_id, inst_id, (i+1));
			}
		}
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return ret=%d, exemMask=0x%x,optMask=0x%x\n",
		__FUNCTION__,__LINE__,ret,me_info->mask,me_info->opt_mask);
	return ret;
}

int omci_me_general_get_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	uint16_t class_id = 0, inst_id = 0, cur_mask = 0, set_mask = 0;
	omci_attr_dscp_ptr omci_attr = NULL;
	int i = 0, ret = 0 ;

    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: Enter\n",__FUNCTION__,__LINE__);

	if((NULL == me_entry)||(NULL == me_info)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	class_id = me_info->class_id;
	inst_id = me_info->inst_id;
	set_mask = me_info->mask;

	if(omci_is_voip_related_me(class_id))
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]VOIP CONFIG_Method is not OMCI, nothing to do in adapter. class_id:%d, inst_id:%d\n",
					__FUNCTION__,__LINE__, class_id, inst_id);
		return -1;
	}

	for(i = 0; i < 16; i++){
		cur_mask = 1 << (15-i);
		omci_attr = me_entry->omci_attr_dscp_list+(i+1);
		if((NULL == omci_attr)||(255 == omci_attr->attriIndex)){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: attribute end.\n",__FUNCTION__,__LINE__);
			break;
		}
		if(cur_mask & set_mask){
			if((ATTR_UNSUPPORT != omci_attr->support)&&(NULL != omci_attr->func)&&(NULL != omci_attr->func->get_val)){
				ret = omci_attr->func->get_val(me_info, omci_attr);
				if(ret == 0){
					/* bbf247: Special treatment for ME 277(Priority Queue) PacketDropThresh and DropPrecColourMark */
					if( (me_info->class_id == OMCI_CLASS_ID_PRIORITY_QUEUE && (cur_mask == 1 || cur_mask == (1 << 3)) && bbf247_enable) ||
						(me_info->class_id == OMCI_CLASS_ID_PPTP_ETHERNET_UNI && cur_mask == (1 << 8) && bbf247_enable) )
						;
					else
						me_info->mask &= (~cur_mask);
				} else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get attribute failed! class_id:%d, inst_id:%d, attr_idx:%d\n",__FUNCTION__,__LINE__
						, class_id, inst_id, (i+1));
				}
			}else{ /* Adapter do nothing for this attribute action*/
				ret = 0;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]Nothing to do in adapter. class_id:%d, inst_id:%d, attr_idx:%d\n",__FUNCTION__,__LINE__
					, class_id, inst_id, (i+1));
			}
		}
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return ret=%d, exemMask=0x%x\n",
		__FUNCTION__,__LINE__,ret,me_info->mask);
	return ret;
}

void omci_me_start_test(void *arg)
{
	testThreadPara_t *ptr=(testThreadPara_t *)arg;
	management_entry_ptr me_entry=NULL;
	omci_me_info_ptr me_info=NULL;

	if(ptr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
		return ;
	}

	me_entry = ptr->me_entry;
	me_info = ptr->me_info;
	if(me_entry != NULL && me_info != NULL && me_entry->func != NULL && me_entry->func->test_me!= NULL)
	{	
		me_entry->func->test_me(me_entry, me_info);
	}

	if(ptr->me_entry != NULL){
		free(ptr->me_entry);
		ptr->me_entry = NULL;
	}
	if(ptr->me_info != NULL){
		if(ptr->me_info->attributes != NULL){
			free(ptr->me_info->attributes);
			ptr->me_info->attributes = NULL;
		}
		free(ptr->me_info);
		ptr->me_info = NULL;
	}
	free(ptr);
	ptr = NULL;

	return ;
}
int omci_me_test_msg_hander(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	int result=-1;
	int ret = 0; 
	testThreadPara_t* testThreadPara = NULL;	
	management_entry_ptr me_entry_cpy = NULL;
	omci_me_info_ptr me_info_cpy = NULL;
	pthread_t thread_id;
	pthread_attr_t thread_attr;
	uint8_t * me_attr_cpy=NULL;

    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

	switch (me_info->class_id){
		case OMCI_CLASS_ID_ANI_G: 
			result = ani_g_test_support(me_info);
			break;
		case OMCI_CLASS_ID_ONU_G: 
			result = onu_g_test_support(me_info);
			break;
		case OMCI_CLASS_ID_PPTP_POTS_UNI: 
			result = pptp_pots_uni_test_support(me_info);
			break;
		default: 
			goto end;
			break;
	}

	//create a thread and start test
	testThreadPara = malloc(sizeof(testThreadPara_t));	
	if(testThreadPara == NULL){
		return -1;
	}
	me_entry_cpy = malloc(sizeof(management_entry_t));
	if(me_entry_cpy == NULL){
		free(testThreadPara);
		return -1;
	}
	me_info_cpy = malloc(sizeof(omci_me_info_t));	
	if(me_info_cpy == NULL){
		free(testThreadPara);
		free(me_entry_cpy);
		return -1;
	}

	me_attr_cpy = malloc(OMCI_EXTENDED_MSG_CONT_LEN);	
	if(me_attr_cpy == NULL){
		free(testThreadPara);
		free(me_entry_cpy);
		free(me_info_cpy);
		return -1;
	}

	memcpy(me_entry_cpy,me_entry,sizeof(management_entry_t));
	memcpy(me_info_cpy,me_info,sizeof(omci_me_info_t));
	memcpy(me_attr_cpy,me_info_cpy->attributes,OMCI_EXTENDED_MSG_CONT_LEN);	
		
	testThreadPara->me_entry = me_entry_cpy;
	testThreadPara->me_info = me_info_cpy;
	testThreadPara->me_info->attributes = me_attr_cpy;

	ret = pthread_attr_init(&thread_attr);
	if(ret != 0)
	{
		free(testThreadPara);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] attribute creation fail!", __FUNCTION__, __LINE__);
		return -1;
	}
	ret = pthread_attr_setstacksize(&thread_attr, MAX_STACK_SIZE);
	if(ret != 0)
	{		
		free(testThreadPara);		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Set stacksize fail!", __FUNCTION__, __LINE__);		
		goto return_error;	
	}
	ret = pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED); 
	if(ret != 0)
	{
		free(testThreadPara);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Set attribute fail!\n",__FUNCTION__, __LINE__);
		goto return_error;
	}
	if( pthread_create(&thread_id, &thread_attr, (void *)omci_me_start_test, (void*)testThreadPara) != 0 ){
		fprintf(stderr, "pthread_create error!!\n");
		pthread_attr_destroy(&thread_attr);
		if(me_attr_cpy != NULL){
			free(me_attr_cpy);
			me_attr_cpy = NULL;
		}
		if(me_info_cpy != NULL){
			free(me_info_cpy);
			me_info_cpy = NULL;
		}
		if(me_entry_cpy != NULL){
			free(me_entry_cpy);
			me_entry_cpy = NULL;
		}
		if(testThreadPara != NULL){
			free(testThreadPara);
			testThreadPara = NULL;
		}
		exit(0);
	}
	pthread_attr_destroy(&thread_attr);

end:			
	return result;
return_error:
	pthread_attr_destroy(&thread_attr);
	return -1;
}


/*************************************************
************PM general function*********************/

int omci_me_general_pm_history_create_del_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    pm_history_data_list_ptr currNode = NULL;
    pm_history_data_list_ptr prevNode = NULL;
    uint8_t *pm_content = NULL;
    uint8_t len = 0;
    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    if(omci_pm_is_extend_pm_me(me_info->class_id))
        len = 16;
    else
        len = 2;
    
    pthread_mutex_lock(&pmListLock);

    if(me_info->msg_type == MT_OMCI_MSG_TYPE_CREAT)
    {
        if(pm_history_data_list ==  NULL)
        {
            pm_history_data_list = calloc(1, sizeof(pm_history_data_list_t));
            currNode = pm_history_data_list;
        }
        else
        {
            currNode = pm_history_data_list;
            while(currNode->next != NULL)
            {
                currNode = currNode->next;
            }
            currNode->next = calloc(1, sizeof(pm_history_data_list_t));
            currNode = currNode->next;
        }
        pm_content = (uint8_t *)&currNode->pm_data;
        *((uint16_t *)pm_content) = me_info->inst_id;
        pm_content = pm_content + 3;
        memcpy(pm_content, me_info->attributes+3, len);
        if(omci_pm_is_extend_pm_me(me_info->class_id))
            omci_pm_parse_extend_pm_ctrl_block(&currNode->ctrl_block, me_info->attributes+3);
        currNode->classId = me_info->class_id;
        currNode->instId = me_info->inst_id;
        currNode->next = NULL;
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]add PM NodeclassId = %d, instId = %x. thresholdId= %x\n",__FUNCTION__,__LINE__, 
                                    currNode->classId, currNode->instId, currNode->pm_data.fec_pm.thdDataHalfId);
    }
    else if(me_info->msg_type == MT_OMCI_MSG_TYPE_DELETE)
    {
        currNode = pm_history_data_list;
        prevNode = pm_history_data_list;
        if(currNode != NULL && currNode->instId == me_info->inst_id && currNode->classId == me_info->class_id)
        {
            pm_history_data_list = currNode->next;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]del PM NodeclassId = %d, instId = %x.\n",__FUNCTION__,__LINE__, currNode->classId, currNode->instId);
			free(currNode);
			currNode = NULL;
			pthread_mutex_unlock(&pmListLock);
            return 0;
        }
        while(currNode != NULL)
        {
            if(currNode->instId == me_info->inst_id&& currNode->classId == me_info->class_id)
            {
                prevNode->next = currNode->next;
				if(currNode != NULL){
					omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]del PM NodeclassId = %d, instId = %x.\n",__FUNCTION__,__LINE__, currNode->classId, currNode->instId);
					free(currNode);
					currNode = NULL;
				}
                break;
            }
            prevNode = currNode;
            currNode = currNode->next;
        }        
    }
    else
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pm list msg type[%d] is error.\n",__FUNCTION__,__LINE__, me_info->msg_type);
		pthread_mutex_unlock(&pmListLock);
        return -1;
    }
    pthread_mutex_unlock(&pmListLock);
	return 0;	
}

int omci_me_general_pm_history_set_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	pm_history_data_list_ptr currNode = NULL;
	uint8_t len = 0;
	uint8_t *pm_content = NULL;
    
    if(me_entry == NULL || me_info == NULL || me_info->attributes == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }    

    if(omci_pm_is_extend_pm_me(me_info->class_id))
        len = 16;
    else
        len = 2;
        
    pthread_mutex_lock(&pmListLock);
	currNode = pm_history_data_list;
    while(currNode != NULL)
    {
        if(currNode->classId == me_info->class_id && currNode->instId == me_info->inst_id)
        {
            pm_content = (uint8_t *)&currNode->pm_data;
            memcpy(pm_content+3, me_info->attributes+3, len);
            if(omci_pm_is_extend_pm_me(me_info->class_id))
                omci_pm_parse_extend_pm_ctrl_block(&currNode->ctrl_block, me_info->attributes+3);
        }
        currNode = currNode->next;
    }
    pthread_mutex_unlock(&pmListLock);
	return 0;
}

int omci_me_general_pm_history_get_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    pm_history_data_list_ptr currNode = NULL;
    
    if(me_entry == NULL || me_info == NULL || me_info->attributes == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }    
    pthread_mutex_lock(&pmListLock);
	currNode = pm_history_data_list;
    while(currNode != NULL)
    {
        if(currNode->classId == me_info->class_id && currNode->instId == me_info->inst_id)
        {
            memcpy(me_info->attributes, (uint8_t *)&currNode->pm_data, me_entry->attr->attrLen);
        }
        currNode = currNode->next;
    }
    pthread_mutex_unlock(&pmListLock);
    return 0;
}


static int omci_pm_get_history_data_from_drivers(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    switch(pm_list->classId)
    {
        case OMCI_CLASS_ID_FEC_PM_DATA:
            get_fec_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_MAC_BRIDGE_PMHD:
            get_mac_bridge_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_MAC_BRIDGE_PORT_PMHD:
            get_mac_br_port_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_UP_PMHD:
            get_eth_frame_up_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_DOWN_PMHD:
            get_eth_frame_down_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_GEM_PORT_NETWORK_CTP_PM:
            get_gemport_net_ctp_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ENERGY_CONSUMPTION_PM:
            get_energy_consumed_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_GEM_PORT_PM:
            get_gemport_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_GAL_ETHERNET_PM:
            get_gal_eth_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA:
            get_eth_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_2:
            get_eth2_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_3:
            get_eth3_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM:
            get_eth_frame_extend_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM_64_BIT:
            get_eth_frame_extend_64bit_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_IP_HOST_PM:
            get_iphost_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_TCP_UDP_PM:
            get_tcp_udp_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ENHANCED_FEC_PM_DATA:
            get_enhanced_fec_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_XGPON_TC_PM:
            get_xgpon_tc_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_XGPON_DS_MGNT_PM:
            get_xgpon_ds_mgnt_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_XGPON_US_MGNT_PM:
            get_xgpon_us_mgnt_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ENHANCED_TC_PM:
            get_enhanced_tc_pm_history_data(pm_list, syncFlag);
            break;
#ifdef TCSUPPORT_VOIP
        case OMCI_CLASS_ID_CALL_CTRL_PM_HISTORY:
            get_call_ctrl_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_RTP_PM_HISTORY_DATA:
            get_rtp_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_SIP_AGENT_PM_HISTORY:
            get_sip_agent_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_SIP_CALL_INIT_PM_HISTORY:        
            get_sip_call_init_pm_history_data(pm_list, syncFlag);
            break;
#endif
#ifdef TCSUPPORT_OMCI_ALCATEL
        case OMCI_CLASS_ID_TOTAL_GEM_PORT_PM:
            get_alcatel_total_gemport_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_ETHERNET_TRAFFIC_PM:
            get_alcatel_eth_traffic_pm_history_data(pm_list, syncFlag);
            break;
        case OMCI_CLASS_ID_GEMPORT_PROTOCOL_MONITORING_HISTORY_DATA_PART_2:
            get_alcatel_gemport_2_pm_history_data(pm_list, syncFlag);
            break;
#endif        
        default:
            break;

    }
    return 0;
}

int omci_pm_is_extend_pm_me(uint16_t classId)
{
   if( classId == OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM
        || classId == OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM_64_BIT)
        return 1;
   else
        return 0;
}

void omci_pm_parse_extend_pm_ctrl_block(extend_pm_ctrl_block_ptr info, uint8_t *content)
{
    info->threshold_id = get16(content);
    info->parent_me_classId = get16(content+2);
    info->parent_me_instId = get16(content+4);
    info->accumulation_disable = get16(content+6);
    info->tca_disable = get16(content+8);
    info->control_field = get16(content+10);
    info->tci = get16(content+12);
    info->reserved = get16(content+14);
}


static int omci_pm_tca_event_dispatch(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    switch(pm_list->classId)
    {
        case OMCI_CLASS_ID_FEC_PM_DATA:
            omci_me_fec_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_MAC_BRIDGE_PMHD:
            omci_me_mac_bridge_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_MAC_BRIDGE_PORT_PMHD:
            omci_me_mac_br_port_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_UP_PMHD:
            omci_me_eth_frame_up_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_DOWN_PMHD:
            omci_me_eth_frame_down_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_GEM_PORT_NETWORK_CTP_PM:
            omci_me_gemport_net_ctp_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_GEM_PORT_PM:
            omci_me_gem_port_pm_history_notify(pm_list, threshold_info);
    	    break;
        case OMCI_CLASS_ID_GAL_ETHERNET_PM:
            omci_me_gal_eth_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA:
            omci_me_eth_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_2:
            omci_me_eth2_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA_3:
            omci_me_eth3_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM:
            omci_me_eth_frame_extend_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM_64_BIT:
            omci_me_eth_frame_extend_64bit_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_IP_HOST_PM:
            omci_me_iphost_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_TCP_UDP_PM:
            omci_me_tcp_udp_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_XGPON_DS_MGNT_PM:
            omci_me_xgpon_ds_mgnt_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ENHANCED_FEC_PM_DATA:
            omci_me_enhanced_fec_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_XGPON_TC_PM:
             omci_me_xgpon_tc_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ENHANCED_TC_PM:
             omci_me_enhanced_tc_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ENERGY_CONSUMPTION_PM:
            /*no tca*/
            break;
#ifdef TCSUPPORT_VOIP
        case OMCI_CLASS_ID_CALL_CTRL_PM_HISTORY:
            omci_me_call_ctrl_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_RTP_PM_HISTORY_DATA:
            omci_me_rtp_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_SIP_AGENT_PM_HISTORY:
            omci_me_sip_agent_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_SIP_CALL_INIT_PM_HISTORY:
            omci_me_sip_call_init_pm_history_notify(pm_list, threshold_info);
            break;
#endif
#ifdef TCSUPPORT_OMCI_ALCATEL
        case OMCI_CLASS_ID_TOTAL_GEM_PORT_PM:
            omci_me_alcatel_total_gemport_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_ETHERNET_TRAFFIC_PM:
            omci_me_alcatel_eth_traffic_pm_history_notify(pm_list, threshold_info);
            break;
        case OMCI_CLASS_ID_GEMPORT_PROTOCOL_MONITORING_HISTORY_DATA_PART_2:
            /*no tca*/
            break;
#endif
        default:
            break;

    }
    return 0;
}

int omci_pm_clear_list_for_mibrest()
{
    pm_history_data_list_ptr currNode = NULL;
    pm_history_data_list_ptr prevNode = NULL;
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] enter\n", __FUNCTION__, __LINE__);
    pthread_mutex_lock(&pmListLock);
	currNode = pm_history_data_list;
    while(currNode != NULL)
    {
        prevNode = currNode;
        currNode = currNode->next;
		if(prevNode != NULL){
			free(prevNode);
			prevNode = NULL;
		}
    }
    pm_history_data_list = NULL;
    pthread_mutex_unlock(&pmListLock);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] leave\n", __FUNCTION__, __LINE__);
    return 0;
}
uint8_t omci_pm_is_end_of_interval_time()
{
    return endIntervalFlag;
}
uint8_t omci_pm_report_alarm_by_tca_info(tca_notify_info_t info, uint8_t clearAlarm)
{
    evt_alarm_data_t alarm_info = {0};
    uint8_t reportFlag = 0;
    if(!clearAlarm)/*0~15min*/
    {
    #if 0
        if (info.threshold == 0)
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] threshold value is 0, return\n", __FUNCTION__, __LINE__);
            return info.reportFlag;
        }
    #endif
        if( info.currentData > info.threshold && info.reportFlag == 0)/*first greater threshold, reporter alarm*/
        {
            reportFlag = 1;
            alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] current data greater threshold, current = %llu, threshold = %llu\n", 
                                            __FUNCTION__, __LINE__, info.currentData, info.threshold);
        }
        else if(info.currentData <= info.threshold && info.reportFlag == 1)/*first lower threshold, clear alarm*/
        {
            reportFlag = 0;
            alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] current data lower threshold, current = %llu, threshold = %llu\n", 
                                            __FUNCTION__, __LINE__, info.currentData, info.threshold);
        }
        else
            return info.reportFlag;
        
    }
    else/*at the end of 15min*/
    {
        if(info.reportFlag == 0)/*the attribute had not reported alarm*/
            return info.reportFlag;
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] at the end of 15min or other case, clear the alarm\n", __FUNCTION__, __LINE__);
        reportFlag = 0;
        alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
    }

    alarm_info.class_id = info.classId;
    alarm_info.inst_id = info.instId;
    alarm_info.alarm_num = info.alarm_num;
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] report TCA classId = %d, instId = %x, alarm_num = %d, %s \n", __FUNCTION__, __LINE__, 
            alarm_info.class_id, alarm_info.inst_id, alarm_info.alarm_num,
            alarm_info.alarm_flag == OMCI_ALARM_CLEAR ?"OMCI_ALARM_CLEAR":"OMCI_ALARM_HAPPEND");
    omci_adpt_report_event(OMCI_EVENT_TCA, &alarm_info);

    return reportFlag;
}

static float omci_pm_transfer_optical_power(float power_mw)
{
	float log_value = 0;
	log_value = 10*logFunction(power_mw, 10, 4);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "power_mw : %f, dB_value :%f\n", power_mw, log_value);
	return log_value;
}

static void clearTxRxPowerAlarm(evt_alarm_data_t alarm_info, uint8_t PreAlarmNum, int preFlag)
{
    alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
    omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
    omciScreenPrintf("[%s][%d]clear power alarmNum(%d) first, then report the alarm\n",__FUNCTION__, __LINE__, alarm_info.alarm_num);
    if(preFlag == LOWER_POWER || preFlag == UPPER_POWER)
    {
        omciScreenPrintf("[%s][%d]clear power last %s alarm, alarmNum is (%d)\n",__FUNCTION__, __LINE__, preFlag==LOWER_POWER?"lower":"higher", PreAlarmNum);
        alarm_info.alarm_num = PreAlarmNum;
        omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
    }
}
static int omci_pm_alarm_tx_rx_power(void)
{
/* ani port  OMCI_CLASS_ID_ANI_G*/
	int rxPowerLower = 0;
	int rxPowerUpper = 0;
	int txPowerLower = 0;
	int txPowerUpper = 0;
	PHY_PARAMS_t phyTransParams ={0};
	float powerMw = 0.0;
	float rxPower = 0.0;
	float txPower = 0.0;
	float rxPowerLowerTh = 0.0;
	float rxPowerUpperTh = 0.0;
	float txPowerLowerTh = 0.0;
	float txPowerUpperTh = 0.0;
    evt_alarm_data_t alarm_info = {0};
    uint16_t instId = 0;
    int state_change = 0;

	if(gponmgr_lib_get_phy_trans_params(&phyTransParams)) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]gponmgr_lib_get_phy_trans_params is fail.\n",__FUNCTION__,__LINE__);
		return -1 ;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]Temperature:%x, Voltage:%x, TxCurrent:%x, TxPower:%x, RxPower:%x\n",__FUNCTION__,__LINE__,
		phyTransParams.temperature, phyTransParams.voltage, phyTransParams.txCurrent, phyTransParams.txPower, phyTransParams.rxPower);

	if(omci_lib_get_inst_list_by_classid(OMCI_CLASS_ID_ANI_G, &instId, 1) <= 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: omci_lib_get_inst_list_by_classid fail!\n",__FUNCTION__,__LINE__);
		return -1;		
	}

	/*SF */

	/*SD */
	powerMw = phyTransParams.rxPower * 0.0001;
	if (powerMw == 0.0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]power rx mw = 0.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	rxPower = omci_pm_transfer_optical_power(powerMw);

	omci_lib_get_rxPower_lowerThreshold(&rxPowerLower);
	
	/*received optical power*/
	if(rxPowerLower == RX_POWER_DEFAULT_POLICY || rxPowerLower == RDKB_DEFAULT_POLICY){
		rxPowerLowerTh = -28.0;
	}else{
		rxPowerLowerTh = rxPowerLower *(-0.5);
	}


	omci_lib_get_rxPower_upperThreshold(&rxPowerUpper);

	if(rxPowerUpper == RX_POWER_DEFAULT_POLICY || rxPowerUpper == RDKB_DEFAULT_POLICY){
		rxPowerUpperTh = -8.0;
	}else //invalid data, set max value
	{
		rxPowerUpperTh = rxPowerUpper *(-0.5);
	}

    alarm_info.class_id = OMCI_CLASS_ID_ANI_G;
    alarm_info.inst_id = instId;	
	if(rxPower <= rxPowerLowerTh) //lower
	{
	    if(pmTcaPreInfo.preRxFlag != LOWER_POWER)
	    {
	        alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
	        alarm_info.alarm_num = OMCI_ALARM_ID_LOW_RX_OPTICAL;
	        clearTxRxPowerAlarm(alarm_info, OMCI_ALARM_ID_HIGH_RX_OPTICAL, pmTcaPreInfo.preRxFlag);
	        pmTcaPreInfo.preRxFlag = LOWER_POWER;
	        state_change = 1;
	    }
	}
	else if(rxPower <= rxPowerUpperTh) //normal
	{
	    if(pmTcaPreInfo.preRxFlag != NORMAL_POWER)
	    {
	        
	        alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
	        if(pmTcaPreInfo.preRxFlag == LOWER_POWER)
	            alarm_info.alarm_num = OMCI_ALARM_ID_LOW_RX_OPTICAL;
	        else
	            alarm_info.alarm_num = OMCI_ALARM_ID_HIGH_RX_OPTICAL;
	        pmTcaPreInfo.preRxFlag = NORMAL_POWER;
	        state_change = 1;
	    }
	}
	else //higher
	{
	    if(pmTcaPreInfo.preRxFlag != UPPER_POWER)
	    {
	        alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
	        alarm_info.alarm_num = OMCI_ALARM_ID_HIGH_RX_OPTICAL;
	        clearTxRxPowerAlarm(alarm_info, OMCI_ALARM_ID_LOW_RX_OPTICAL, pmTcaPreInfo.preRxFlag);
	        pmTcaPreInfo.preRxFlag = UPPER_POWER;
	        state_change = 1;
	    }
	}
	
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]rxPower:%f, rxPowerLowerTh:%f, rxPowerUpperTh:%f\n",__FUNCTION__,__LINE__,rxPower, rxPowerLowerTh, rxPowerUpperTh);
	if (state_change == 1)
    {
        omciScreenPrintf("[%s][%d]rx power alarm %s, rxPower:%f, rxPowerLowerTh:%f, rxPowerUpperTh:%f\n",__FUNCTION__,__LINE__,
                                (alarm_info.alarm_flag== OMCI_ALARM_HAPPEND) ? "happened":"clear",rxPower, rxPowerLowerTh, rxPowerUpperTh);
        omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
        state_change = 0;
    }
    
	powerMw = phyTransParams.txPower * 0.0001;
	if (powerMw == 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]power tx mw = 0.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	txPower = omci_pm_transfer_optical_power(powerMw);

	omci_lib_get_txPower_lowerThreshold(&txPowerLower);
	/* transmit optical power */
	if(txPowerLower == TX_POWER_DEFAULT_POLICY || txPowerLower == RDKB_DEFAULT_POLICY){
		txPowerLowerTh = OMCI_DEFAULT_TX_POWER_LOWER_THLD;
	}else//invalid data, set min value
	{
		txPowerLowerTh = txPowerLower * (0.5);
	}

	omci_lib_get_txPower_upperThreshold(&txPowerUpper);
	if(txPowerUpper == TX_POWER_DEFAULT_POLICY || txPowerUpper == RDKB_DEFAULT_POLICY){
		txPowerUpperTh = OMCI_DEFAULT_TX_POWER_UPPER_THLD;
	}else{
		txPowerUpperTh = txPowerUpper * (0.5);
	}
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]txPower:%f, txPowerLowerTh:%f, txPowerUpperTh:%f\n",__FUNCTION__,__LINE__,txPower, txPowerLowerTh, txPowerUpperTh);
	
    if(txPower <= txPowerLowerTh) //lower
	{
	    if(pmTcaPreInfo.preTxFlag != LOWER_POWER)
	    {
	        alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
	        alarm_info.alarm_num = OMCI_ALARM_ID_LOW_TX_OPTICAL;
	        clearTxRxPowerAlarm(alarm_info, OMCI_ALARM_ID_HIGH_TX_OPTICAL, pmTcaPreInfo.preTxFlag);
	        pmTcaPreInfo.preTxFlag = LOWER_POWER;
	        state_change = 1;
	    }
	}
	else if(txPower <= txPowerUpperTh) //normal
	{
	    if(pmTcaPreInfo.preTxFlag != NORMAL_POWER)
	    {
	        
	        alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
	        if(pmTcaPreInfo.preTxFlag == LOWER_POWER)
	            alarm_info.alarm_num = OMCI_ALARM_ID_LOW_TX_OPTICAL;
	        else
	            alarm_info.alarm_num = OMCI_ALARM_ID_HIGH_TX_OPTICAL;
	        pmTcaPreInfo.preTxFlag = NORMAL_POWER;
	        state_change = 1;
	    }
	}
	else //higher
	{
	    if(pmTcaPreInfo.preTxFlag != UPPER_POWER)
	    {
	        alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
	        alarm_info.alarm_num = OMCI_ALARM_ID_HIGH_TX_OPTICAL;
	        clearTxRxPowerAlarm(alarm_info, OMCI_ALARM_ID_LOW_TX_OPTICAL, pmTcaPreInfo.preTxFlag);
	        pmTcaPreInfo.preTxFlag = UPPER_POWER;
	        state_change = 1;
	    }
	}

	if (state_change == 1)
    {
        omciScreenPrintf("[%s][%d]tx power alarm %s, txPower:%f, txPowerLowerTh:%f, txPowerUpperTh:%f\n",__FUNCTION__,__LINE__,
                                (alarm_info.alarm_flag== OMCI_ALARM_HAPPEND) ? "happened":"clear", txPower, txPowerLowerTh, txPowerUpperTh);
        omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
        state_change = 0;
    }
    
	return 0;
}

static int omci_pm_alarm_lan_port_up_down(void)
{
    unsigned char curStatus[MAX_ETH_PORT_NUM_ARRAY] = {0};
    evt_alarm_data_t alarm_info = {0};
    evt_avc_data_t avc_info = {0};
	uint16_t *inst_id_array = NULL;
	int inst_count = 0, i = 0;
	uint8_t port = 0;
	lanport_info_t lanport_info;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] Enter.\n",__FUNCTION__,__LINE__);
    if(LINK_UP != omci_info_g.trafficStatus){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] ONU Traffic down.\n",__FUNCTION__,__LINE__);
        return 0;
    }
    /*get ME information*/
	if(omci_lib_get_inst_count_by_classid(OMCI_CLASS_ID_PPTP_ETHERNET_UNI, &inst_count) != 0 || inst_count == 0){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] OMCI_CLASS_ID_PPTP_ETHERNET_UNI do not exist.\n",__FUNCTION__,__LINE__);
        return 0;
	}
	
	if(blapi_traffic_get_lanport_info(&lanport_info) == -1){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] call blapi_traffic_get_lanport_info failed.\n",__FUNCTION__,__LINE__);		
		return -1;
	}
	
	inst_id_array = malloc(sizeof(uint16_t) * inst_count);
	if(inst_id_array == NULL || omci_lib_get_inst_list_by_classid(OMCI_CLASS_ID_PPTP_ETHERNET_UNI, inst_id_array, inst_count) <= 0){
        if(NULL != inst_id_array){
    		free(inst_id_array);
    		inst_id_array = NULL;
    	}
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] OMCI_CLASS_ID_PPTP_ETHERNET_UNI instance info do not exist.\n",__FUNCTION__,__LINE__);
        return 0;
	}
    for (i = 0; i < inst_count; i++)
    {
        port = getPortIdxByInstId(inst_id_array[i]);
		//if(port >= MAX_ETH_PORT_NUM_ARRAY){
		if(port > LANPORT_INFO_MAX_PORT){                     //in definition of lanport_info, max port num is 8 
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] port num is greater than MAX_ETH_PORT_NUM_ARRAY.\n",__FUNCTION__,__LINE__);
			continue;
		}
		port = xsi_lanport_info_covert(port);
		port--;
		curStatus[port] = (strcmp(lanport_info.lan_status[port], "UP") == 0) ? ETH_LINK_UP : ((strcmp(lanport_info.lan_status[port], "DOWN") == 0) ? ETH_LINK_DOWN : ETH_LINK_UNKNOW);     
		if (curStatus[port] == pmTcaPreInfo.preStatus[port]){
			continue;
		}
		alarm_info.class_id = OMCI_CLASS_ID_PPTP_ETHERNET_UNI;
		alarm_info.inst_id = inst_id_array[i];
		alarm_info.alarm_num = OMCI_ALARM_ID_PPTPEthernetUNI_LAN_LOS_ALARM;

		avc_info.class_id = OMCI_CLASS_ID_PPTP_ETHERNET_UNI;
		avc_info.inst_id = inst_id_array[i];
		avc_info.avc_index = OMCI_AVC_ID_PPTPEthernetUNI_OPERATIONAL_STATE;
		if (ETH_LINK_DOWN == curStatus[port])
		{   
			alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
			avc_info.avc_data[0] = ETH_LINK_DOWN;
			
		}
		else
		{   
			alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
			avc_info.avc_data[0] = ETH_LINK_UP;
		}
		
		omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
		omci_adpt_report_event(OMCI_EVENT_AVC, &avc_info);
		pmTcaPreInfo.preStatus[port] = curStatus[port];
    }

    if(NULL != inst_id_array){
		free(inst_id_array);
		inst_id_array = NULL;
	}
    return 0;
}

static int omci_pm_alarm_sipua_pots(void)
{
    char nodeName[64] = {0};
    uint8_t alarm_num[SIPUA_REG_FAIL+1] = {255, 255, OMCI_ALARM_ID_SIP_USER_DATA_SIPUA_REG_AUTH, OMCI_ALARM_ID_SIP_USER_DATA_SIPUA_REG_TIMEOUT, OMCI_ALARM_ID_SIP_USER_DATA_SIPUA_REG_FAIL};
	unsigned char curAlarm[VOIP_MAX_CHAN_NUM]={SIPUA_REG_INIT,SIPUA_REG_INIT};
	uint8_t port = 0;
	char regStatus[32]={0};
	char failReson[8]={0};
	int fainIndex=0;
	evt_alarm_data_t alarm_info = {0};
    uint16_t *inst_id_array = NULL;
	int inst_count = 0;

	if(LINK_UP != omci_info_g.trafficStatus){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] ONU Traffic down.\n",__FUNCTION__,__LINE__);
        return 0;
    }
	if(omci_lib_get_inst_count_by_classid(OMCI_CLASS_ID_SIP_USER_DATA, &inst_count) != 0 || inst_count == 0){
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] OMCI_CLASS_ID_SIP_USER_DATA do not exist.\n",__FUNCTION__,__LINE__);
        return 0;
	}
	
	inst_id_array = malloc(sizeof(uint16_t) * inst_count);
	if(inst_id_array == NULL || omci_lib_get_inst_list_by_classid(OMCI_CLASS_ID_SIP_USER_DATA, inst_id_array, inst_count) <= 0){
        if(NULL != inst_id_array){
    		free(inst_id_array);
    		inst_id_array = NULL;
    	}
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] OMCI_CLASS_ID_SIP_USER_DATA can not get instance info.\n",__FUNCTION__,__LINE__);
    	return 0;
	}
	inst_count = (inst_count > VOIP_MAX_CHAN_NUM)?VOIP_MAX_CHAN_NUM:inst_count;
	for(port=0; port < inst_count; port++){
		snprintf(nodeName,sizeof(nodeName), "InfoVoIP_Entry%d", port);
		omci_tcapi_nget(nodeName, "Status", regStatus, sizeof(regStatus));
		if(strcmp(regStatus,"Error")==0){
			omci_tcapi_nget(nodeName, "RegFailReason", failReson, sizeof(failReson));
			fainIndex=atoi(failReson);
			switch(fainIndex){
				case VOICE_USER_PW_ERROR:				
					curAlarm[port]=SIPUA_REG_AUTH;
					break;
				case VOICE_ROUTE_ERROR:
				case VOICE_RESPONSE_ERROR:
					curAlarm[port]=SIPUA_REG_TIMEOUT;
					break;
				case VOICE_UNKNOWN_ERROR:
					curAlarm[port]=SIPUA_REG_FAIL;
					break;
				default:
					break;
			}
			
		}else if(strcmp(regStatus,"Up")==0){
			curAlarm[port]=SIPUA_REG_UP;
		}
		
		if(pmTcaPreInfo.preAlarm[port] != curAlarm[port]){
			switch(curAlarm[port]){	
				case SIPUA_REG_AUTH:					
		 		case SIPUA_REG_TIMEOUT:	
		 		case SIPUA_REG_FAIL:
		 		    alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
		 		    alarm_info.alarm_num = alarm_num[curAlarm[port]];
				    break;
				case SIPUA_REG_UP:
				    alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
				    alarm_info.alarm_num = alarm_num[pmTcaPreInfo.preAlarm[port]];
					break;
				default:
					break;
					
			}
			alarm_info.class_id = OMCI_CLASS_ID_SIP_USER_DATA;
			alarm_info.inst_id = inst_id_array[port];
			omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
			pmTcaPreInfo.preAlarm[port] = curAlarm[port];
		}
	
	}

	if(NULL != inst_id_array){
		free(inst_id_array);
		inst_id_array = NULL;
	}
	return 0;
}


static void omci_pm_reset_pre_info(void)
{
	int i = 0;
	pmTcaPreInfo.preRxFlag = NORMAL_POWER;
	pmTcaPreInfo.preTxFlag = NORMAL_POWER;
	for(i = 0; i < MAX_ETH_PORT_NUM; i++){
		pmTcaPreInfo.preStatus[i] = ETH_LINK_UNKNOW;
	}
	for(i = 0; i < VOIP_MAX_CHAN_NUM; i++){
		pmTcaPreInfo.preAlarm[i] = SIPUA_REG_UP;
	}
}

#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CT_LOOPDETECT)
static int omci_pm_alarm_lan_port_loopdetect(void)
{
	evt_alarm_data_t alarm_info = {0};
	uint16_t *inst_id_array = NULL;
	int inst_count = 0, i = 0;
	uint8_t port = 0;
	static uint8_t alarmHistory = 0;
	int status = 0;
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] Enter.\n",__FUNCTION__,__LINE__);
    if(LINK_UP != omci_info_g.trafficStatus){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] ONU Traffic down.\n",__FUNCTION__,__LINE__);
        return 0;
    }
    /*get ME information*/
	if(omci_lib_get_inst_count_by_classid(OMCI_CLASS_ID_PPTP_ETHERNET_UNI, &inst_count) != 0 || inst_count == 0){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] OMCI_CLASS_ID_PPTP_ETHERNET_UNI do not exist.\n",__FUNCTION__,__LINE__);
        return 0;
	}
	
	inst_id_array = malloc(sizeof(uint16_t) * inst_count);
	if(inst_id_array == NULL || omci_lib_get_inst_list_by_classid(OMCI_CLASS_ID_PPTP_ETHERNET_UNI, inst_id_array, inst_count) <= 0){
        if(NULL != inst_id_array){
    		free(inst_id_array);
    		inst_id_array = NULL;
    	}
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] OMCI_CLASS_ID_PPTP_ETHERNET_UNI instance info do not exist.\n",__FUNCTION__,__LINE__);
        return 0;
	}
	for (i = 0; i < inst_count; i++)
    {
        port = (inst_id_array[i] & PPTP_UNI_PORT_ID_MASK) -1;
		status = getLoopStatus(port);
		/*alarmHistory 0-3bit ->0-3port*/
		if((status != PPTP_UNI_NO_LOOPBACK_STATUS) && (!(alarmHistory & (1 << port))))
		{
			alarmHistory |= (1 << port);
			alarm_info.class_id = OMCI_CLASS_ID_PPTP_ETHERNET_UNI;
        	alarm_info.inst_id = inst_id_array[i];
        	alarm_info.alarm_num = omci_lan_port_loopdetect_alarm_num;
			alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
			omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
		}
		if((status == PPTP_UNI_NO_LOOPBACK_STATUS) && (alarmHistory & (1 << port)))
		{	
			alarmHistory &= ~(1 << port);
			alarm_info.class_id = OMCI_CLASS_ID_PPTP_ETHERNET_UNI;
        	alarm_info.inst_id = inst_id_array[i];
        	alarm_info.alarm_num = omci_lan_port_loopdetect_alarm_num;
			alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
			omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
		}
	}
	if(NULL != inst_id_array){
		free(inst_id_array);
		inst_id_array = NULL;
	}
    return 0;
}

static void omci_ME65528_alarm_loop_detection(void)
{
	evt_alarm_data_t alarm_info = {0};
	int inst_count = 0;
	uint8_t port = 0;
	static uint8_t alarmHistory = 0;
	int status = 0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] Enter.\n",__FUNCTION__,__LINE__);
    if(LINK_UP != omci_info_g.trafficStatus){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] ONU Traffic down.\n",__FUNCTION__,__LINE__);
    }

	/*get ME information*/
	if(omci_lib_get_inst_count_by_classid(OMCI_CLASS_ID_PPTP_ETHERNET_UNI, &inst_count) != 0 || inst_count == 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] OMCI_CLASS_ID_PPTP_ETHERNET_UNI do not exist.\n",__FUNCTION__,__LINE__);
	}

	for(port = 0; port < 4; port++)
	{
		status = getLoopStatus(port);
		
		if(status == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] get loop status error,don't report alarm.\n",__FUNCTION__,__LINE__);
			return;
		}

		if((status != ME65528_NO_LOOPBACK_STATUS) && (!(alarmHistory & (1 << port))))
		{
			alarmHistory |= (1 << port);
			alarm_info.class_id = OMCI_CLASS_ID_CTC_ONU_LOOP_DETECTION;
        	alarm_info.inst_id = 0;//this private ME only has one instanceID
        	alarm_info.alarm_num = port;//the private ME has four alarm num from 0-3,which correspond to the lan port num
			alarm_info.alarm_flag = OMCI_ALARM_HAPPEND;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]Report Alarm:Class_Id %d,alarm_num %d,flag %d\n",
				__FUNCTION__,__LINE__,alarm_info.class_id,alarm_info.alarm_num,alarm_info.alarm_flag);
			omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
		}
		if((status == ME65528_NO_LOOPBACK_STATUS) && (alarmHistory & (1 << port)))
		{	
			alarmHistory &= ~(1 << port);
			alarm_info.class_id = OMCI_CLASS_ID_CTC_ONU_LOOP_DETECTION;
        	alarm_info.inst_id = 0;
        	alarm_info.alarm_num = port;
			alarm_info.alarm_flag = OMCI_ALARM_CLEAR;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]Report Alarm:Class_Id %d,alarm_num %d,flag %d\n",
				__FUNCTION__,__LINE__,alarm_info.class_id,alarm_info.alarm_num,alarm_info.alarm_flag);
			omci_adpt_report_event(OMCI_EVENT_ALARM, &alarm_info);
		}
	}

}

#endif/*TCSUPPORT_COMPILE*/

//2s
int omci_pm_tca_notify(void)
{
    enum{ MAX_THRESHOLD_DATA_NUM = 3};
    omci_me_info_t me_info = {0};
    pm_history_data_list_ptr currNode = NULL;    
    uint8_t *pm_content = NULL;
    int i = 0;
    uint16_t threshold_data[MAX_THRESHOLD_DATA_NUM] = {OMCI_CLASS_ID_THRESHOLD_DATA1, OMCI_CLASS_ID_THRESHOLD_DATA2, OMCI_CLASS_ID_THRESHOLD_DATA_64_BIT};
    int startIdx = 0;
    int endIdx = 0;
	uint16_t pm_content_temp_data = 0;

#if 0
    if(!syncTimeEnd)
    {
        timerStopS(tca_timerId);
        tca_timerId = INVALID_TIMERID;
        omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG, "[%s][%d]sync time do not finished, do not generate TCA event.\n",__FUNCTION__,__LINE__);
        return 0;
    }
#endif
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CT_LOOPDETECT)
	omci_pm_alarm_lan_port_loopdetect();
	omci_ME65528_alarm_loop_detection();
#endif/*TCSUPPORT_COMPILE*/
    omci_pm_alarm_lan_port_up_down();
    omci_pm_alarm_sipua_pots();
    omci_pm_alarm_tx_rx_power();
    pthread_mutex_lock(&pmListLock);
	currNode = pm_history_data_list;
    while(currNode != NULL)
    {
        pm_content = (uint8_t *)&currNode->pm_data;

        if(OMCI_CLASS_ID_ETHERNET_PM_HISTORY_DATA == currNode->classId)/*threshold data 1 and 2*/
        {
            startIdx = 0;
            endIdx = MAX_THRESHOLD_DATA_NUM-1;
        }
        else if(OMCI_CLASS_ID_ETHERNET_FRAME_EXTENDED_PM_64_BIT == currNode->classId    /*threshold data 64bit*/
               || OMCI_CLASS_ID_ENHANCED_FEC_PM_DATA == currNode->classId
               || OMCI_CLASS_ID_ENHANCED_TC_PM == currNode->classId)
        {
            startIdx = MAX_THRESHOLD_DATA_NUM-1;
            endIdx = MAX_THRESHOLD_DATA_NUM;
        }
        else/*threshold data 1*/
        {
            startIdx = 0;
            endIdx = 1;
        }
		
		memcpy(&pm_content_temp_data,pm_content+3,sizeof(uint16_t));
		me_info.inst_id = pm_content_temp_data;//threshold id
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]inst_id:0x%x,the PM ME Content first 5 byte, 0x%02x %02x %02x %02x %02x.\n",__FUNCTION__,__LINE__, 
                                    me_info.inst_id,pm_content[0],pm_content[1],pm_content[2],pm_content[3],pm_content[4]);
        for(i = startIdx; i < endIdx; i++)
        {
            me_info.class_id = threshold_data[i];
            if(omci_attr_get_all_data_except_table_attr(&me_info) == 0)
            {
                omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]the PM ME = %d, thresholdId = %x find threshold data [%d], start to TCA Verify.\n",__FUNCTION__,__LINE__, currNode->classId,  me_info.inst_id, me_info.class_id);
        		omci_pm_tca_event_dispatch(currNode, me_info);
        	}
        	else
        	{
        	    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]the PM ME = %d ,thresholdId = %x, can not find threshold data [%d].\n",__FUNCTION__,__LINE__, currNode->classId, me_info.inst_id,  me_info.class_id);
        	}
    	}
        
        currNode = currNode->next;
    }
    pthread_mutex_unlock(&pmListLock);
    if(endIntervalFlag == 1) //update pm history data
    {
        endIntervalFlag = 0;
    }
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]stop tca timer id = %d.\n",__FUNCTION__,__LINE__,tca_timerId);
    if (tca_timerId > 0)
    {
        timerStopS(tca_timerId);
        tca_timerId = 0;
    }
    tca_timerId = timerStartS(2*TIMER_COUNT_S, (TimerCallback)omci_pm_tca_notify, NULL);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]get tca timer id = %d.\n",__FUNCTION__,__LINE__,tca_timerId);
    return 0;
}

static void omci_adpt_init_std_omci_map()
{
    int i = 1;
    int omciMeTableSize = sizeof(adpt_std_me)/sizeof(management_entry_t);
    if(omciMeTableSize > OMCI_MAX_MAP_NUM)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s] Enter omci_adpt_init_std_omci_map max=%d greater %d\n",__FUNCTION__, omciMeTableSize, OMCI_MAX_MAP_NUM);
        omciMeTableSize = OMCI_MAX_MAP_NUM;
    }
    memset(&stdOmciAdptIndexMap, 0, sizeof(stdOmciAdptIndexMap));
    for(i = 1; i < omciMeTableSize; i++)
    {
        if(adpt_std_me[i].omciMeClassId >= OMCI_MAX_MAP_NUM)
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"Enter omci_adpt_init_std_omci_map classId=%d greater %d\n", adpt_std_me[i].omciMeClassId, OMCI_MAX_MAP_NUM);
            continue;
        }
        stdOmciAdptIndexMap[adpt_std_me[i].omciMeClassId] = i;
    }
}

static int omci_adpt_is_event_monitored(omci_evt_id_t event_id)
{
	uint32_t event_id_mask = 0;
	event_id_mask = 1 << event_id;
	if(event_id_mask & g_event_mask){
		return 0;
	}else{
		return -1;
	}
}

int omci_adpt_report_event(omci_evt_id_t event_id, void *event_val)
{
	if(omci_adpt_is_event_monitored(event_id) == 0){
		omci_lib_send_event(event_id, event_val);
	}
	return 0;
}

/*******************************************************************************************
**function name
	omci_adpt_commit_node_list_timeout
**description:
	when timer timeout execute tcapi_commit node
 **retrun :
 	-1:	failure
 	0:	success
**parameter:
********************************************************************************************/
int omci_adpt_commit_node_list_timeout(void)
{
	int ret = 0;
	commitNode_p pNode = NULL;
	commitNode_p preNode = NULL;
	char nodeName[32] = {0};
	
	pthread_mutex_lock(&commitNodeList.lock);
	if(NULL == commitNodeList.pHeadNode){
		ret = -1;
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"pNodelist not have commit node!\r\n ");
		goto end;
	}
	pNode = commitNodeList.pHeadNode;
	while(NULL != pNode){
		memset(nodeName,0,sizeof(nodeName));
		memcpy(nodeName, pNode->nodeName, sizeof(nodeName));
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%s][%d] commit Node %s\n",__FILE__,__FUNCTION__, __LINE__,nodeName);
		omci_tcapi_commit(nodeName);
		preNode = pNode;
		pNode = pNode->next;
		if(NULL != preNode){
			free(preNode);
			preNode = NULL;
		}
	}
	commitNodeList.pHeadNode = NULL;
	
end:
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]\n ", __FUNCTION__, __LINE__);
    timerStopS(commitNodeTimeId);
	commitNodeTimeId = INVALID_TIMERID;
	pthread_mutex_unlock(&commitNodeList.lock);
	return ret;
}

/******************************************************************************
******************************************************************************/
static int omci_adpt_commit_node_list_destory(void)
{
	commitNode_p pNode = NULL;
	commitNode_p preNode = NULL;
	char nodeName[32] = {0};
	 
	pthread_mutex_lock(&commitNodeList.lock);
	pNode = commitNodeList.pHeadNode;
	while(NULL != pNode){
		memset(nodeName,0,sizeof(nodeName));
		memcpy(nodeName, pNode->nodeName, sizeof(nodeName));
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%s][%d] commit Node %s\n",__FILE__,__FUNCTION__, __LINE__,nodeName);
		omci_tcapi_commit(nodeName);
		preNode = pNode;
		pNode = pNode->next;
		if(NULL != preNode){
			free(preNode);
			preNode = NULL;
		}
	}
	commitNodeList.pHeadNode = NULL;
    pthread_mutex_unlock(&commitNodeList.lock);
	pthread_mutex_destroy(&commitNodeList.lock);

	return 0;
}

static commitNode_p* omci_adpt_find_node(commitNode_p* pNode,char* nodeName){
	commitNode_p* p = NULL;

	if(pNode == NULL || nodeName == NULL){
		omciScreenPrintf("commitNode_P or nodeName is null,return!\n");
		return NULL;
	}
	
	p = pNode;
	while((*p != NULL) && (strcmp((*p)->nodeName,nodeName) != 0)){
		p = &((*p)->next);
	}
	return p;
}


/*******************************************************************************************
**function name
	omci_adpt_add_commit_node_list
**description:
	add commit node	to the commitNodeList
 **retrun :
 	-1:	failure
 	0:	success
**parameter:
********************************************************************************************/
static int omci_adpt_add_commit_node_list(char* nodeName){
	int ret = 0;
	commitNode_p newNode = NULL;
	commitNode_p* pNode = NULL;

	pthread_mutex_lock(&commitNodeList.lock);
	pNode = omci_adpt_find_node(&(commitNodeList.pHeadNode),nodeName);
	if(pNode == NULL){
		omciScreenPrintf("!!!pNode is null,return -1!\n");
		pthread_mutex_unlock(&commitNodeList.lock);
		return -1;
	}

	if(NULL == *pNode){
		newNode = (commitNode_p)malloc(sizeof(commitNode_t));
		if(NULL == newNode){
			ret = -1;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"Node space application fail!\r\n ");
			goto end;
		}
		memset(newNode,0,sizeof(commitNode_t));
		strncpy(newNode->nodeName, nodeName, sizeof(newNode->nodeName)-1);
		newNode->next = NULL;
		*pNode = newNode;
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]\n ", __FUNCTION__, __LINE__);
	}

end:
	pthread_mutex_unlock(&commitNodeList.lock);
	return ret;
}

/*******************************************************************************************
**function name
	omci_adpt_delay_omci_commit_node
**description:
	add commit node	to the commitNodeList and start or restart the timer
 **retrun :
 	-1:	failure
 	0:	success
**parameter:
********************************************************************************************/

int omci_adpt_delay_omci_commit_node(char* nodeName)
{
	if(omci_adpt_add_commit_node_list(nodeName) !=0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_adpt_add_commit_node_list fail\n");
		return -1;	
	}
	if(INVALID_TIMERID == commitNodeTimeId){    
		commitNodeTimeId = timerStartS(10*TIMER_COUNT_S , (TimerCallback)omci_adpt_commit_node_list_timeout, NULL);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] commitNodeTimeId = %d\n ", __FUNCTION__, __LINE__, commitNodeTimeId);
	}
		
	return 0;
}


#ifdef TCSUPPORT_OPENWRT
static struct uci_package *config_init_package(const char *config)
{
		struct uci_context *ctx = uci_ctx;
		struct uci_package *p = NULL;
	
		if (!ctx) {
			ctx = uci_alloc_context();
			uci_ctx = ctx;
	
			ctx->flags &= ~UCI_FLAG_STRICT;
			if (config_path)
				uci_set_confdir(ctx, config_path);
	
#ifdef DUMMY_MODE
			uci_set_savedir(ctx, "./tmp");
#endif
		} else {
			p = uci_lookup_package(ctx, config);
			if (p)
				uci_unload(ctx, p);
		}
	
		if (uci_load(ctx, config, &p))
			return NULL;
	
		return p;
}

static int omci_adpt_init_uci_config(void)
{
	char *err;
	uci_network = config_init_package("network");
	if (!uci_network) {
		uci_get_errorstr(uci_ctx, &err, NULL);
		if(err != NULL)
			free(err);
		return -1;
	}

	return 0;
}


int found_sfu_wanIF(void)
{
	int is_found = 0;
	const char * buff;
	char tmp[MAX_BUFFER_SIZE] = {0};
	struct uci_element *element;
	
	omci_adpt_init_uci_config();

	sprintf(tmp,"%d",HYBRID_WAN_VLAN_ID);
	uci_foreach_element(&uci_network->sections, element) {
		struct uci_section *section = uci_to_section(element);
		if (strncmp(section->type, "wan_vlan",strlen("wan_vlan")) != 0) {
			continue;
		}
		buff  = uci_lookup_option_string(uci_ctx, section, "vlan_id");
		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n find uci vlan is %s\n",buff);
		is_found = (strcmp(tmp,buff) == 0);
		if(is_found)
			return 1;
		
	}
	return 0;
}
#endif

 int pon_get_hybrid_sfu_lanif(char (*lanif)[MAX_BUFFER_SIZE])
{	
	unsigned int hyPortMmask=0; 
	int i = 0;
	int j = 0;
	int ruleNum = 0;
	pon_vlan_rule vlanRules[OMCI_MAX_PORT_VLAN_RULE_NUM] = {{0}};
	char tmp[MAX_BUFFER_SIZE] = {0};
	int is_found = 0;
	
	pon_get_hybrid_port_masks(&hyPortMmask);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"hyPortMmask=%x\n",hyPortMmask);

	for(i = 1; i <= 4; i++)
	{
		ruleNum = pon_get_vlan_rule(OMCI_VLAN_BASIC_LAN_PORT_VAL + i, vlanRules);		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n omciTrafficUpHandler port:%d, ruleNum:%d!\n",
			OMCI_VLAN_BASIC_LAN_PORT_VAL + i, ruleNum);
		if(ruleNum > 0)
		{
			for(j = 0; j < ruleNum; j++)
			{
				if(((vlanRules[j].treatment_method > 20 
					&& vlanRules[j].treatment_method < 43)
					|| vlanRules[j].treatment_method == 0)){  // ???

					if((hyPortMmask & (0x01 << (i-1))) == 0)
						continue;
					
					is_found = 1;
					omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n set eth0.%d!\n",i);
					sprintf(tmp, "eth0.%d", i);
					strcpy(lanif[i-1], tmp);
					break;
				}
			}
		}

	}
	return is_found;
}

void pon_set_hybrid_sfu_lan(char (*lanif)[MAX_BUFFER_SIZE])
{	
	int i = 0;

	for(i = 0; i <= 3; i++)
	{
		if(strlen(lanif[i]) > 0)
		{
			pon_add_hybrid_sfu_lan(lanif[i]);
			omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n add hybrid lan port=%d\n",i + 1);
		}
	}	
} 


static int omci_adpt_set_gpon_phy_status(char * status){
	char nodeName[20] = {0};
	char timec[10]={0};
	struct timespec ponstarttime;

	if(status == NULL){
		return -1;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Enter %s [%d] status = %s\n",__FUNCTION__,__LINE__,status);
	if(strcmp(status,PONCOMMON_XPON_PHY_GPON_UP) == 0){
		/*kill epon_oam thread*/
		if((omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_GPON) 
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_XGPON)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_XGSPON)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_NGPON2_10G_10G)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_NGPON2_10G_2G)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_NGPON2_2G_2G)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_GPON_SYM)){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE," %s [%d]: GPON Mode kill epon_oam \n",__FUNCTION__,__LINE__);
			system("killall epon_oam");
		}
		/*If is epon mode clear general rule*/
		if((omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_EPON) 
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_10G_1G_EPON)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_10G_10G_EPON) 
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_1G_1G_EPON)
			|| (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_TURBO_EPON)){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE," %s [%d]:EPON->GPON->clear  pon rule \n",__FUNCTION__,__LINE__);
			omci_me_clear_xpon_rule();	
		}
        
		/*update xpon_common phy status attribute value*/
		omci_tcapi_set("XPON_Common", PONCOMMON_ATTR_XPON_PHY_STATUS, PONCOMMON_XPON_PHY_GPON_UP);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE," %s [%d]: set XPON_Common gpon phy up \n",__FUNCTION__,__LINE__);
		if(TCSUPPORT_CT_PHONEAPP_VAL){	
			//store currtime
			clock_gettime(CLOCK_MONOTONIC,&ponstarttime);
			sprintf(timec,"%d",(int)ponstarttime.tv_sec);
			omci_tcapi_set("mobile_Entry", "PONstarttime", timec);	
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE," %s [%d]: set mobile_Entry PONstarttime \n",__FUNCTION__,__LINE__);
		}		
	}
	else if(strcmp(status,PONCOMMON_XPON_PHY_GPON_DOWN) == 0){
		strcpy(nodeName,"XPON_Common");
		omci_tcapi_set(nodeName, PONCOMMON_ATTR_XPON_PHY_STATUS, PONCOMMON_XPON_PHY_GPON_DOWN);
		omci_tcapi_set(nodeName, PONCOMMON_ATTR_DATA_TRAFFIC_STA, ONU_WAN_DATA_LINK_DOWN);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "receive GPON LOS trap message->gpon phy down\n") ;
	}else{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "omci->setPhysta->error!\n") ;
		return -1;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Exit %s [%d] \n",__FUNCTION__,__LINE__);
	return 0;

}

static int omci_adpt_phy_alarm_handler(uint32_t trapValue)
{
	/*for phy alarm threshold is not the same as olt set, it is conflict with pmmgr gponAlarmHandle*/
	return 0;
}

static int omci_adpt_pon_up_wake_up_wan(uint8_t state)
{
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s] [%d] ENTER\n",__FUNCTION__,__LINE__);
	if(!TCSUPPORT_CT_PON_VAL)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s] [%d] TCSUPPORT_CT_PON_VAL is not defined\n",__FUNCTION__,__LINE__);
		return 0;
	}
	

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s] [%d] state = %d\n",__FUNCTION__,__LINE__, state);

	if (state == 1) {
	  	system("echo 1 > /tmp/pon_up");
		//ponTmId = 0; /* stop this timer */
	}
	else
		unlink("/tmp/pon_up");
	
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s] [%d] LEAVE\n",__FUNCTION__,__LINE__);
    
  	return 0;
}

void omci_adpt_stop_timer(void)
{
	omci_pm_reset_pre_info();
    timerStopS(tca_timerId);    
    tca_timerId = INVALID_TIMERID;

    timerStopS(commitNodeTimeId);    
    commitNodeTimeId = INVALID_TIMERID;
	if(setQueueMapTimer> 0){
		timerStopS(setQueueMapTimer);
		setQueueMapTimer = INVALID_TIMERID;
	}
	if(commitWanTimer> 0){
		timerStopS(commitWanTimer);
		commitWanTimer = INVALID_TIMERID;
	}
	if(ipOptionId[0]> 0){
		timerStopS(ipOptionId[0]);
		ipOptionId[0] = INVALID_TIMERID;
	}
	if(ipOptionId[1] > 0){
		timerStopS(ipOptionId[1]);
		ipOptionId[1] = INVALID_TIMERID;
	}
	if(recfgTimerId> 0){
		timerStopS(recfgTimerId);
		recfgTimerId = INVALID_TIMERID;
	}
	if(tmrIdImage> 0){
		timerStopS(tmrIdImage);
		tmrIdImage = INVALID_TIMERID;
	}
	if(tmrIdSecMiss> 0){
		timerStopS(tmrIdSecMiss);
		tmrIdSecMiss = INVALID_TIMERID;
	}
}
				
#ifdef TCSUPPORT_PON_SFU_HGU_HYBRID
#ifdef TCSUPPORT_OPENWRT
int omci_adpt_traffic_up_handler(void)
{	
	int hybrid_sfu_found = 0;
	char lanif[4][MAX_BUFFER_SIZE] = {0};
	char wanif[MAX_BUFFER_SIZE] = {0};

	if(HGU != omci_info_g.onuType){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"sfu mode, do nothing\n");
		return 0;
	}

	//reset hybrid
	pon_reset_hybrid();
	
	//find availble SFU wan if
	if(FALSE == found_sfu_wanIF()){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n No available wan interface!\n");
		return -1;
	}	

	hybrid_sfu_found = pon_get_hybrid_sfu_lanif(lanif);
	if(hybrid_sfu_found)
	{
		sprintf(wanif,"pon.%d",HYBRID_WAN_VLAN_ID);
		pon_hybrid_enable(1);
		pon_set_hybrid_sfu_br_wan(wanif);
		pon_set_hybrid_sfu_lan(lanif);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n set hybrid done\n");
	}
	else
	{
		pon_hybrid_enable(0);
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"%s %d end\n",__FUNCTION__,__LINE__);
	return 0;	
		
}

#else
int omci_adpt_traffic_up_handler(void)
{
	pon_vlan_rule vlanRules[OMCI_MAX_PORT_VLAN_RULE_NUM] = {{0}};
	int i, j, ruleNum, is_found;
	char node[MAX_BUFFER_SIZE] = {0};
	char attr[MAX_BUFFER_SIZE] = {0};
	char tmp[MAX_BUFFER_SIZE] = {0};
	char lanif[4][MAX_BUFFER_SIZE];
	static char wanif[MAX_BUFFER_SIZE] = {0};
	static int wanIdx = -1;
	unsigned int hyPortMmask=0; 

	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"omci_adpt_traffic_up_handler enter!\n");
	if(HGU != omci_info_g.onuType){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"sfu mode, do nothing\n");
		return 0;
	}

	//reset hybrid
	pon_reset_hybrid();
	blapi_pon_del_portbind_grp(8);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"reset hybrid done; del the portbind done!\n");

	//check the wan PVC which used before
	if(wanIdx == -1){		
		for(i = 0; i < 8; i++)
		{
			sprintf(node, "Wan_PVC%d_Entry", i);
			if((omci_tcapi_nget(node, "IsHybrid", attr,sizeof(attr)) == 0) && (0 == strcmp(attr,"Yes") ))
			{
				wanIdx = i;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"find used Hybrid wan, wanIdx=%d\n",wanIdx);
				omci_tcapi_set(node, "Active", "No");
				if(omci_tcapi_commit(node) != 0)
				{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG, "\r\n[%s]:tcapi_commit fail ![%d]\n",__FUNCTION__,__LINE__);
					return -1;
				}
			}
		}
	}

	/* search an available WAN PVC which inactive for bridge WAN. */
	if(wanIdx == -1){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG, "\r\n[%s] search an available Wan PVC\n",__FUNCTION__);
		for(i = 0; i < 8; i++)
		{
			sprintf(node, "Wan_PVC%d_Entry", i);
			if((omci_tcapi_nget(node, "Active", attr,sizeof(attr)) == 0) && (0 == strcmp(attr,"No") ) ){
				wanIdx = i;	
				break;
			}
		}
	}
		
	if(wanIdx == -1)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n No available wan interface!\n");
		return -1;
	}

	sprintf(node, "Wan_PVC%d_Entry", wanIdx);
	memset(wanif, 0, sizeof(wanif));
	sprintf(tmp, "nas%d_0", wanIdx);
	strcpy(wanif, tmp);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"wanIdx=%d, wanif=%s\n",wanIdx,wanif);

	/* find the sfu lan ports. */
	is_found = 0;
	memset(lanif, 0, sizeof(lanif));
	pon_get_hybrid_port_masks(&hyPortMmask);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"hyPortMmask=%x\n",hyPortMmask);

	for(i = 1; i <= 4; i++)
	{
		ruleNum = pon_get_vlan_rule(OMCI_VLAN_BASIC_LAN_PORT_VAL + i, vlanRules);		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n omciTrafficUpHandler port:%d, ruleNum:%d!\n",
			OMCI_VLAN_BASIC_LAN_PORT_VAL + i, ruleNum);
		if(ruleNum > 0)
		{
			for(j = 0; j < ruleNum; j++)
			{
				if(((vlanRules[j].treatment_method > 20 
					&& vlanRules[j].treatment_method < 43)
					|| vlanRules[j].treatment_method == 0)){  // ???

					if((hyPortMmask & (0x01 << (i-1))) == 0)
						continue;
					
					is_found = 1;
					omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n set eth0.%d!\n",i);
					sprintf(tmp, "eth0.%d", i);
					strcpy(lanif[i-1], tmp);
					break;
				}
			}
		}

	}
	if(is_found)
	{
		/* create a bridge wan. */
		omci_tcapi_set(node, "Active", "Yes");
		omci_tcapi_set(node, "ISP", "3");
		omci_tcapi_set(node, "IPVERSION", "IPv4");
		omci_tcapi_set(node, "dot1q", "Passth");
		omci_tcapi_set(node, "IsHybrid", "Yes");
		omci_tcapi_set(node, "BridgeMode", "IP_Bridged");
		omci_tcapi_set(node, "DHCPRealy", "Yes");//set ebtables for DHCP packages
		omci_tcapi_set(node, "VLANMode", "TRANSPARENT");
		omci_tcapi_set(node, "WanMode", "Bridge");
		
		/* set hybrid info for ponvlan. */
		pon_hybrid_enable(1);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n set hybrid info for ponvlan done\n");
		
		/* set port binding. */
		for(i = 1; i <= 4; i++)
		{
			if(strlen(lanif[i-1]) > 0)
			{
				pon_add_hybrid_sfu_lan(lanif[i-1]);
				omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n add hybrid lan port=%d\n",i);
				sprintf(tmp, "LAN%d", i);
				omci_tcapi_set(node, tmp, "Yes");
			}
			else{
				sprintf(tmp, "LAN%d", i);
				omci_tcapi_set(node, tmp, "No");
			}		
		}
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n portbind done\n");
		if(omci_tcapi_commit(node) != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG, "\r\n[%s]:tcapi_commit fail ![%d]\n",__FUNCTION__,__LINE__);
			return -1;
		}
						
		pon_set_hybrid_sfu_br_wan(wanif);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"\r\n set hybrid wan done\n");
	}
	else{
		for(i = 1; i <= 4; i++)
		{
			sprintf(tmp, "LAN%d", i);
			omci_tcapi_set(node, tmp, "No");
		}
		omci_tcapi_set(node, "Active", "No");
		if(omci_tcapi_commit(node) != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG, "\r\n[%s]:tcapi_commit fail ![%d]\n",__FUNCTION__,__LINE__);
			return -1;
		}		
		wanIdx = -1;
		pon_hybrid_enable(0);
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"%s %d end\n",__FUNCTION__,__LINE__);
	return 0;
}
#endif
#endif
static int omci_adpt_trap_handler(XPON_EVENT_t *pEvent)
{
	int ret = 0 ;
	static int tcontCounts = 0;
	static int gponTcontAlloced = 0;
	char attr[20] = {0};
	omci_evt_id_t event_id = OMCI_EVENT_MAX_ID;
	void *event_val = NULL;
	int link_mode = 0;

	if(NULL == pEvent){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s [%d] pEvent is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Enter %s [%d] pEvent->id = %d\n",__FUNCTION__,__LINE__,pEvent->id);

	switch(pEvent->id) {
		case XMCS_EVENT_GPON_LOS:
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "receive GPON LOS trap message\n") ;
			strcpy(attr,PONCOMMON_XPON_PHY_GPON_DOWN);
			AuthStatusFlag = 0;
			omci_tcapi_set("GPON_LOIDAuth", "AuthStatus", "0");
			omci_adpt_set_gpon_phy_status(attr);
			omci_adpt_stop_timer();
			syncTimeEnd = 0;
			event_id = OMCI_EVENT_PHY_LOS;
			omciSaveEvent(event_id);
			break ;
		case XMCS_EVENT_GPON_PHY_READY:
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "receive GPON PHY_READY trap message\n") ;
			
			strcpy(attr,PONCOMMON_XPON_PHY_GPON_UP);
			omci_adpt_set_gpon_phy_status(attr);
			event_id = OMCI_EVENT_PHY_READY;
			omciSaveEvent(event_id);
			break ;
		case XMCS_EVNET_GPON_DEACTIVATE:
			omci_adpt_pon_up_wake_up_wan(0);
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "receive GPON DEACTIVATE trap message\n") ;
			omciSaveEvent(XMCS_EVNET_GPON_DEACTIVATE);
			break ;
		case XMCS_EVENT_GPON_ACTIVATE:
			gponTcontAlloced = 0;
			if(TCSUPPORT_XPON_LED_VAL){
				xponLedNeedBlink = 1;
			}
			strcpy(attr,PONCOMMON_XPON_PHY_GPON_UP);
			omci_adpt_set_gpon_phy_status(attr);
			omci_adpt_pon_up_wake_up_wan(1);
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "receive GPON ACTIVATE trap message\n");
			omciSaveEvent(XMCS_EVENT_GPON_ACTIVATE);
			break ;
		case XMCS_EVENT_GPON_DISABLE:
			omci_adpt_set_emergency(1);
			omciSaveEvent(XMCS_EVENT_GPON_DISABLE);
			break;
		case XMCS_EVENT_GPON_ENABLE:
			omci_adpt_set_emergency(0);
			omciSaveEvent(XMCS_EVENT_GPON_ENABLE);
			break;
		case XMCS_EVENT_GPON_TCONT_ALLOCED:
			gponTcontAlloced ++;

			if(XMCS_IF_WAN_DETECT_MODE_GPON == omci_onu_cap_g.linkMode || XMCS_IF_WAN_DETECT_MODE_GPON_SYM== omci_onu_cap_g.linkMode || XMCS_IF_WAN_DETECT_MODE_AUTO == omci_onu_cap_g.linkMode){
				if (pEvent->value < OMCI_ONU_ID_MAX_NUM_1G)
					omci_info_g.onuId = pEvent->value;
			}else{
				if (pEvent->value < OMCI_ONU_ID_MAX_NUM_10G)
				omci_info_g.onuId = pEvent->value;
			}
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "receive GPON alloced TCONT trap message, gponTcontAlloced = %d, tcontCounts = %d, allocId = %d\n", gponTcontAlloced, tcontCounts, pEvent->value) ;
			omciReconfigQueueMappingRule();
			if(omciRecfgIfc() != 0)
			{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n omciSendPktToOmcc->omciRecfgIfc fail[%d]",__LINE__);
			}
			break ;
		case XMCS_EVENT_GPON_MODE_CHANGE:
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"Gpon Mode Change!\n");
			omci_lib_get_link_mode((onu_link_mode_t *)&link_mode);
			if(0 == link_mode)
			{
				event_id = OMCI_EVENT_AUTO_MODE_CHANGE;
				omci_adpt_report_event(event_id,event_val);
			}
			return 0;
		case XMCS_EVENT_GPON_TRAFFIC_STATUS_CHANGE:
			//ponmgr_lib_set_traffic_status((unsigned char)pEvent->value);
			//omci_info_g.trafficStatus = (uint8_t)pEvent->value;
			if((unsigned char)pEvent->value == LINK_UP){
				omciFinishSetWanInfo();
				omci_info_g.trafficStatus = LINK_UP;
				omciScreenPrintf("ponTime:Traffic Up\n");
				omci_pm_tca_notify();
				omci_tcapi_set(XPON_COMMON_NODE, XPON_COMMON_ATTR_TRAFFIC_STA, ONU_WAN_DATA_LINK_UP);
				
#ifdef TCSUPPORT_PON_SFU_HGU_HYBRID				
				//traffic up handler, for HybridMode
				omciScreenPrintf("receive XMCS_EVENT_GPON_TRAFFIC_UP trap message\n");
				omci_adpt_traffic_up_handler();
#endif
			}else{
				omci_info_g.trafficStatus = LINK_DOWN;
				omci_tcapi_set(XPON_COMMON_NODE, XPON_COMMON_ATTR_TRAFFIC_STA, ONU_WAN_DATA_LINK_DOWN);
		}
			break;
		case XMCS_EVENT_GPON_PHY_TRANS_ALARM:
			omci_adpt_phy_alarm_handler(pEvent->value);
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "receive GPON_TRAP_PHY_TRANS_ALARM trap message\n") ;
			break;
		default:
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "receive a unknown trap message, %x\n", pEvent->id) ;
			ret = -1 ;
			break ;
	}
	if(OMCI_EVENT_MAX_ID != event_id){
		omci_adpt_report_event(event_id, event_val);
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Exit %s [%d] ret = %d\n",__FUNCTION__,__LINE__,ret);
	return ret ;
}	

/********************************************************************************************
********************************************************************************************/
static void omci_adpt_trap_destory(void) 
{
	exit(0) ;
}


static void omci_adpt_trap_handler_thread(void)
{
	XPON_EVENT_t event ={0};

	while(1){
        memset(&event, 0, sizeof(XPON_EVENT_t));
        if(ponmgr_lib_get_event_block(&event,EVT_HANDLER_OMCI) != 0){
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "get event failed!\n");
			continue ;
        } else{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "get event id:%u, event value:%u\n",event.id,event.value) ;
        }
		omci_adpt_trap_handler(&event);
		usleep(1000);
	}
	pthread_exit(NULL);
}	

typedef void*(*omci_adpt_thread_callback)(void *param);

int omci_adpt_init_trap_handler(void)
{
    pthread_t mythread;
    int ret;
	pthread_attr_t attr;

	if(omci_trap_thread_ready){
		return 0;
	}

	/*create thread*/
	ret = pthread_attr_init(&attr);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] attribute creation fail!\n",__FUNCTION__, __LINE__);
		return -1;
	}


	ret = pthread_attr_setstacksize(&attr, MAX_STACK_SIZE);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] Set stacksize fail!\n",__FUNCTION__, __LINE__);
		goto return_error;
	}
	//need to set deached way
	ret = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Set attribute fail!\n",__FUNCTION__, __LINE__);
		goto return_error;
	}

	if(0 != pthread_create(&mythread, &attr, (omci_adpt_thread_callback)omci_adpt_trap_handler_thread, NULL)){
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]create omci_adpt_trap_handler_thread fail!\n",__FUNCTION__, __LINE__);
	    return -1;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] create omci_adpt_trap_handler_thread done! \n", __FUNCTION__, __LINE__);

	pthread_attr_destroy(&attr);
	omci_trap_thread_ready = 1;
	return 0;
return_error:
	pthread_attr_destroy(&attr);
	return -1;
}
static int omci_adpt_init_pptp_ether_uni()
{
	int ret = 0;
	uint8_t  portId=0;
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: \n",__FUNCTION__, __LINE__); 

	
	/*Physical path termination point Ethernet UNI*/
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: \n",__FUNCTION__, __LINE__); 

	for(portId = 0; portId < MAX_ECNT_1GETHER_PORT_NUM; portId++) 
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: portId=%d\n",__FUNCTION__, __LINE__,portId); 

		ret = macMT7530GetConfigurationStatus(portId);
		if(ret == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]getPPTPEthernetUNICfgIndValue->macMT7530GetConfigurationStatus fail,portId=%d,ret=%d\n",
				__FUNCTION__,__LINE__,portId,ret);	
		}

		ret = macMT7530SetPauseTime(0, portId);
		if(ret == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]setPPTPEthernetUNIPauseTime->macMT7530SetPauseTime fail\n",__FUNCTION__,__LINE__); 
		}
	}	

#if defined (TCSUPPORT_OMCI_ALCATEL) && defined (TCSUPPORT_UPSTREAM_VLAN_POLICER)	
		InitUpStrmPolicerTrtcm();
#endif
#if defined (TCSUPPORT_TLS)
		omciTLSInfo.lanPort = OMCI_TLS_INVALID_PORT;
		omciTLSInfo.vlan = OMCI_TLS_INVALID_VLAN;
		if(OMCI_TLS_INVALID_PORT != omciTLSInfo.lanPort){
			blapi_traffic_set_tls_port(0, 0);
			omciTLSInfo.lanPort = OMCI_TLS_INVALID_PORT;
		}
		if(OMCI_TLS_INVALID_VLAN != omciTLSInfo.vlan){
			blapi_traffic_set_tls_vlan(0, 0);
			omciTLSInfo.vlan = OMCI_TLS_INVALID_VLAN;
		}
#endif
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CT_LOOPDETECT)
	for(portId = 0; portId < MAX_ECNT_1GETHER_PORT_NUM; portId++)
	{
		ret = setPortLoopDetect(portId,1);
		if(ret == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]setPortLoopDetect port[%d] fail\n",__FUNCTION__,__LINE__,portId); 
		}
	}
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CGNX)
	omci_lan_port_loopdetect_alarm_num = 0xd0;
#endif/*TCSUPPORT_COMPILE*/
#endif/*TCSUPPORT_COMPILE*/
	return ret;
}

static int omci_adpt_init_Loop_Detection(void)
{
	int ret = 0;
	uint8_t  portId=0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: \n",__FUNCTION__, __LINE__); 

	//the default value of loop detection management is 0x0001,means should active it
	for(portId = 0; portId < 4; portId++)
	{
		ret = setPortLoopDetect(portId,1);
		if(ret == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]setPortLoopDetect port[%d] fail\n",__FUNCTION__,__LINE__,portId); 
		}

		ret = setPortDisableLooped(portId,1);
		if(ret == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]setPortDisableLooped port[%d] fail\n",__FUNCTION__,__LINE__,portId); 
		}
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]:init loop detection done \n",__FUNCTION__, __LINE__); 
	
	return ret; 

}

static int mallocTableBuffByGet(management_entry_ptr mePtr, uint8_t *attrStructPtr, uint16_t mask)
{
    int i=0;
    uint16_t offsetOfStruct=0;
    omci_table_attr_t table={NULL,0};
    static int cnt=0;
    if(NULL == mePtr){
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
    	return 0;
    }

    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] Enter. mask=%x\n",__FUNCTION__,__LINE__,mask);
    offsetOfStruct += 2; // 2 byte for instance Id
    for( i = 1; i <= 16; i++)
    {
	    if(mePtr->omci_attr_dscp_list[i].attriIndex == 255)
	        break;

	    if(mask >>(16-i) & 0x0001)
	    {
	    	if(mePtr->omci_attr_dscp_list[i].format == ATTR_FORMAT_TABLE && table.buf == NULL){
	    	    //table process
	    	    table.buf = malloc(OMCI_MAX_TABLE_SIZE);
	    	    table.len = OMCI_MAX_TABLE_SIZE;
	    	    memcpy(attrStructPtr+offsetOfStruct, &table, sizeof(omci_table_attr_t));
	    	    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] allocate table mem. table.len=%d, cnt=%d\n",__FUNCTION__,__LINE__,table.len,++cnt);
	    	}
	    }

	    //calculate offset of Struct
	    if(mePtr->omci_attr_dscp_list[i].format == ATTR_FORMAT_TABLE){
	    	offsetOfStruct  += sizeof(omci_table_attr_t); // table attibute is defined as struct ,include table pointer and table size
	    }
	    else{
	    	offsetOfStruct  += mePtr->omci_attr_dscp_list[i].attriLen;
	    }
    }
    return 0;
}

static int omci_adpt_set_switch_api_for_priority_queue(uint16_t instId)
{
    uint8_t queueId = 0;
    uint8_t portId = 0;
    uint16_t priority = 0;
    backPressure_t backPressure = {0};
	int ret = 0;

	queueId = (uint8_t)((instId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);		

	if(instId < T_CONT_INST_START_ID){
		/*downstream priority queue*/

		/*Allocated Queue size*/
		macMT7530SetAllocatedQueueSize(4, queueId);

		portId = instId/NUM_OF_QUEUE_PER_UIN_PORT + 1;
		priority = instId%NUM_OF_QUEUE_PER_UIN_PORT;
		/*Queue priority*/			
		macMT7530SetQueuePriority(priority, queueId);

		/*weight*/			
		macMT7530SetWeight(1, queueId, portId);
		
		memset(&backPressure, 0, sizeof(backPressure_t));
		backPressure.Enable = 1;	//default value is enable;
		backPressure.time = 0;
		backPressure.MaxQueueThreshold = 0xffff;
		backPressure.MinQueueThreshold = 0;
		ret = macMT7530SetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, portId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]: macMT7530SetBackPressure fail!\n",__FUNCTION__, __LINE__);
			return ret;
		}
	}
#if 0
	else{
		/*upstream priority queue*/

		//wait for pon mac api
		//ret =  ponMacSetAllocatedQueueSize(allocQueueSize, queueId);

		portId = (instId-T_CONT_INST_START_ID)/NUM_OF_QUEUE_PER_TCONT; // T-CONT portID 1~15	
		priority = (instId-T_CONT_INST_START_ID)%NUM_OF_QUEUE_PER_TCONT;
		//wait for pon mac api
		//ret = ponMacSetQueuePriority(priority, queueId);
		//wait for pon mac api
		ret = getPonMacQOSParam(portId, &qosChannel, &qosType, ponWeight);
		if(ret != 0)
		{		
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omciInternalCreateForPriorityQueue: getPonMacQOSParam fail!\n");
			return -1;
		}
		ponWeight[queueId] = 1;
		
		ret = setPonMacQOSParam(qosChannel, qosType, ponWeight);
		if(ret != 0)
		{		
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omciInternalCreateForPriorityQueue: setPonMacQOSParam fail!\n");
				return -1;
		}

		//upstream priority queue
		//wait for pon mac api
		//downstream priority queue
		memset(&backPressure, 0, sizeof(backPressure_t));
		backPressure.Enable = 0;
		backPressure.time = 0;
		backPressure.MaxQueueThreshold = 0xffff;
		backPressure.MinQueueThreshold = 0;
		
		//ret = ponMacSetBackPressure(&backPressure, queueId);		
	}
#endif

	return 0;
}

static int omci_adpt_init_priority_queue(void)
{
    int i, j;
	int ret = 0;

    for(i=0; i<(MAX_TCONT_NUM); i++)
	{
	    /*upstream*/
	    for(j=0; j<NUM_OF_QUEUE_PER_TCONT; j++)
		{
			if(isFiberhome_551601){
				ret = omci_adpt_set_switch_api_for_priority_queue(((i*NUM_OF_QUEUE_PER_TCONT+j)<<8)+T_CONT_INST_START_ID);/*internal create func*/
			} 
			else{
				ret = omci_adpt_set_switch_api_for_priority_queue(i*NUM_OF_QUEUE_PER_TCONT+j+T_CONT_INST_START_ID);/*internal create func*/
			}
	
			if (ret == -1)
			{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "omciInitInstForPriorityQueue: create OMCI_CLASS_ID_PRIORITY_QUEUE fail\n");
				return ret;
			}
		}
	}

#if defined(TCSUPPORT_HGU_OMCI_MIB_UPLOAD_PPTP_ETH_UNI)
    if (HGU != omci_info_g.onuType) 
#endif
    {
    	/*init downstream priority queue*/	
    	for(i=0; i< MAX_ECNT_1GETHER_PORT_NUM; i++)
    	{
    	    for(j=0; j<NUM_OF_QUEUE_PER_UIN_PORT; j++)
    		{
				ret = omci_adpt_set_switch_api_for_priority_queue(i*NUM_OF_QUEUE_PER_UIN_PORT+j);
    		}
        }
    }
	return ret;
}

static int omci_adpt_init_omci_info_variable()
{	
	gponmgr_lib_get_onu_type(&omci_info_g.onuType);
	omci_info_g.onuId = 0;
	omci_info_g.trafficStatus = LINK_DOWN;

	omci_lib_get_omcc_version(&omci_onu_cap_g.omccVersion);
	omci_lib_get_link_mode((onu_link_mode_t*)&omci_onu_cap_g.linkMode);

	return 0;
}

/******************************************************************************
******************************************************************************/
int omci_adpt_socket_init(void)
{
	struct ifreq ifstruct ; 
	int ret = 0;

	omciSocket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) ;
	if(omciSocket == -1) { 
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_adpt_socket_init:create omci socket failed\n") ;
		return -1 ;
	}

	/*RAW communication*/
	socketAddr.sll_family = AF_PACKET ;// PF_PACKET ;	
	socketAddr.sll_protocol = htons(ETH_P_ALL) ;
	strcpy(ifstruct.ifr_name, "omci") ;
	while (1)
	{
		ret = ioctl(omciSocket, SIOCGIFINDEX, &ifstruct) ; 
		if (ret != 0)
		{
			sleep(2);
		}
		else
			break;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "omci_adpt_socket_init: ioctl ret = %x, errno = %x\n", ret, errno);
	socketAddr.sll_ifindex  = ifstruct.ifr_ifindex ;
	
	if(bind(omciSocket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) == -1) { 
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_adpt_socket_init:binding omci socket failed\n") ;
		close(omciSocket) ;
		omciSocket = -1 ;
		return -1 ;
	}
	
	return 0 ;
}
/******************************************************************************
******************************************************************************/
int omci_adpt_socket_destroy(void)
{
	if(omciSocket >= 0) {
		close(omciSocket) ;	
	}

	ubus_client_exit();
	return 0;
}

static int omci_adpt_init_ip_host_wan_interface(void)
{
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%s][%d] clear all wan path\n",__FILE__,__FUNCTION__, __LINE__);
    omci_wan_clear_all();
    memset(g_iphost_wan,0,sizeof(g_iphost_wan));
    omci_wan_init_web_rcd();
    
    omciPPPoEInfo.enable  = FALSE;
    omciPPPoEInfo.iphostId = 0xFF;
    return 0;
}

/************************omci adapt general functions**************************************/


/*______________________________________________________________________________
**	omci_adpt_get_one_string_from_inst
**
**	descriptions:
**		get one string from instance attributeValue_ptr
**	parameters:
**		classId: support OMCI_CLASS_ID_LARGE_STRING,OMCI_CLASS_ID_OCTET_STRING
**		instanceId: 
**		buffer: 
**		length: string length.
**	return:
**		0: success
**		-1:fail
**______________________________________________________________________________
*/
int omci_adpt_get_one_string_from_inst(uint16_t classId, uint16_t instanceId, char *buffer, uint16_t *length)
{
	uint8_t* tmp = NULL;
	uint16_t len = 0;
	omci_large_string_ptr large_string_ptr = NULL;
	omci_octet_string_ptr octet_string_ptr = NULL;
	omci_me_info_t me_info_buf = {0};

	if(buffer == NULL || length == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}

	me_info_buf.class_id = classId;
	me_info_buf.inst_id = instanceId;
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
		return -1;
	}

	switch(classId){
		case OMCI_CLASS_ID_LARGE_STRING:
				large_string_ptr = (omci_large_string_ptr)(me_info_buf.attributes);
				tmp = (uint8_t *)(large_string_ptr->all_part.part);
				len = large_string_ptr->numberOfParts * 25;
				memcpy(buffer, tmp, len);
				break;
		case OMCI_CLASS_ID_OCTET_STRING:
				octet_string_ptr = (omci_octet_string_ptr)(me_info_buf.attributes);
				tmp = (uint8_t *)(octet_string_ptr->all_part.part);
				len = octet_string_ptr->length;
				memcpy(buffer, tmp, len);
				break;				
		default:
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: classId = %d, is not string me class id\n",__FUNCTION__,__LINE__,classId);
			return -1;
	}
	
	*length = len;
	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: return 0, classId=%d, instId=%x, len=%d\n",
		__FUNCTION__, __LINE__,classId,instanceId,len);
	return 0;
}

/*******************************************************************************************
**function name
	omci_adpt_find_row_buf_first_str
**description:
	find the first string in row buffer,
	find the remain buffer in row buffer.
 **retrun :
 	0:	success
 	-1:	failure
**parameter:
	rowBuf: row buffer
	fromLen: from rowBuf+fromLen
	firstStr: first string
********************************************************************************************/
int omci_adpt_find_row_buf_first_str(char * rowBuf, uint32_t * fromLen, char * firstStr)
{
	char *rowPtr = NULL;	
	char buf[64] = {0};
	int len = 0;
	uint32_t currLen = 0;

	if((rowBuf == NULL) || (firstStr == NULL)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] pointer is NULL\n", __FUNCTION__, __LINE__);
		return -1;
	}

    memset(buf, 0, sizeof(buf));
	currLen = *fromLen;
    rowPtr = rowBuf+currLen;
	/*strip the prefix space*/
	while(*rowPtr != '\0'){
		if((*rowPtr != ' ') && (*rowPtr != '\t'))
			break;
		currLen++;
		rowPtr++;
	}
	/*get first Str*/
	if(*rowPtr == '\0'){
		return -1;
	}
	len = 0;
	while(*rowPtr != '\0'){		
		if((*rowPtr == ' ') || (*rowPtr == '\t')){	
			break;
		}
		if(len >=  sizeof(buf)){
			return -1;
		}
		buf[len++] = *rowPtr;
		currLen++;
		rowPtr++;
	}
	buf[sizeof(buf)-1] = '\0';

	strcpy(firstStr, buf);
    * fromLen = currLen;
    
    return 0;

}

int omci_adpt_set_commit_attriubte(char *name, char *attribute, char *value)
{
	int ret = 0;
	ret = omci_tcapi_set(name, attribute, value);
	if (ret != 0)
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_adpt_set_commit_attriubte: tcapi_set fail\n");
	ret = omci_tcapi_set(GPONCOMMONNODE, CURRENTATTRIBUTE, attribute);
	if (ret != 0)
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_adpt_set_commit_attriubte: tcapi_set fail\n");
	ret = omci_tcapi_commit(name);
	if (ret != 0)
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_adpt_set_commit_attriubte: tcapi_commit fail\n");

	return ret;
}

static int omci_adpt_init_after_mibreset(void)
{
    memset(&commitNodeList, 0, sizeof(commitNodeList_t));
	if(pthread_mutex_init(&commitNodeList.lock, NULL) < 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]commitNodeList pthread_mutex_init fail!\n ", __FUNCTION__, __LINE__);
		return -1;
	}
	omci_adpt_stop_timer();

	return 0;
}

static int omci_adpt_retoot_msg_handle(omci_me_info_ptr me_info)
{
#ifdef TCSUPPORT_PON_ROSTELECOM	
	uint16_t class_id = 0;
	uint16_t instId = 0;
	char buf[8] = {0};
	class_id = me_info->class_id;
	instId = me_info->inst_id;

	/*Enter Factory-Reset function*/
	if((class_id == OMCI_CLASS_ID_ONU_G) && (instId == 65281))
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"**Eltex Factory Restore on**\n");
		sprintf(buf, "%d", 2);
		omci_tcapi_set("System_Entry", "reboot_type", buf);
		omci_tcapi_commit("System_Entry");
	}
	else
	{
		blapi_pon_reboot_action();
	}
#else
	/*reboot the ONU*/
	blapi_pon_reboot_action();
#endif
	
	return 0;
}


/******************************************************************************
******************************************************************************/
int omci_lib_adpt_socket_receive(uint8_t *pkts, int *pLen)
{
	int pktLen = 0 ; /*length of the received frame*/ 
    omciGenericPayload_t *rxPkt = (omciGenericPayload_t *)pkts; /*Using device ID, needn't care endian*/

	if(pkts == NULL || pLen == NULL) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]Parameter NULL, fail\n", __FUNCTION__, __LINE__) ;
		return -1 ;
	}
	if(omciSocket < 0) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]omciSocket fail\n", __FUNCTION__, __LINE__) ;
		return -1 ;
	}

	/*if(pLen < OMCI_EXTENDED_MSG_LEN){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"pLen is shorter than OMCI_EXTENDED_MSG_LEN,error\n") ;
		return -1 ;
	}*/
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]start receive data from socket\n", __FUNCTION__, __LINE__) ;
	pktLen = recvfrom(omciSocket, pkts, OMCI_MAX_LENS, 0, NULL, NULL) ;
	if(pktLen < 0) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]receive omci data error\n", __FUNCTION__, __LINE__) ;
		return -1 ;
	}
	*pLen = pktLen ;
	if(OMCI_BASELINE_MSG == rxPkt->devId){
		OmciPktRxCnt.BaseOmciMsgRx ++;
	}else if(OMCI_EXTENED_MSG == rxPkt->devId){
		OmciPktRxCnt.ExtOmciMsgRx ++;
	}else {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s][%d]receive unknown packet\n", __FUNCTION__, __LINE__) ;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]finish receive data from socket\n", __FUNCTION__, __LINE__) ;
	return 0 ;
}

/******************************************************************************
******************************************************************************/
int omci_lib_adpt_socket_transmit(uint8_t *pkts,int len)
{
	int result ;
	if(pkts == NULL) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]Parameter NULL, fail\n", __FUNCTION__, __LINE__) ;
		return -1 ;
	}
	
	if (TCSUPPORT_OMCI_LAN_DEBUG_VAL && gponGetDataFrom == GET_DATA_FROM_DBG_QUEUE){
		//send pkt to lan client			
		result = gponOmciPktTxDbgQ(len, (char *)pkts);
		if(result != 0) { 
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]send lan debug data error\n", __FUNCTION__, __LINE__) ;
			return -1 ;
		}
	}else{
		if(len < OMCI_EXT_CONT_LEN_MIN)
			len = OMCI_EXT_CONT_LEN_MIN;

		result = sendto(omciSocket, pkts, len, 0, (struct sockaddr*)&socketAddr, sizeof(socketAddr)) ;
		if(result == -1) { 
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]send omci data error\n", __FUNCTION__, __LINE__) ;
			return -1 ;
		}
	}
	return 0 ;
}


/******************************************************************************
******************************************************************************/

/* return 0 as success, return -1 as fail. */
int omci_lib_adpt_pkt_handler(omci_me_info_ptr me_info)
{
	uint16_t class_id = 0;
	uint8_t msg_type = 0;
	management_entry_t *adpt_me_entry = NULL;
	omci_synchronize_time_t *sync_time_ptr = NULL;
	int ret = 0;

	if(NULL == me_info){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		ret = -1;
		goto end;
	}
	class_id = me_info->class_id;
	msg_type = me_info->msg_type;

    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] classId = %d,instId=%x,msgType=%d,mask=0x%x, len=%d\n",
		__FUNCTION__,__LINE__, class_id,me_info->inst_id,msg_type,me_info->mask,me_info->attr_len);

    if(msg_type == MT_OMCI_MSG_TYPE_MIB_RESET
    || msg_type == MT_OMCI_MSG_TYPE_SYNC_TIME
    || msg_type == MT_OMCI_MSG_TYPE_REBOOT)
    {
        //do nothing check
    }
    else
    {   	
    	adpt_me_entry = getAdptMeEntryByClassId(me_info->class_id);
    	if(adpt_me_entry == NULL)
    	{
    	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]the classId(%d) can not get the entry.\n",__FUNCTION__,__LINE__, me_info->class_id);
    		return -1;
    	}
    		
    	if(adpt_me_entry->attr == NULL )
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s][%d] adpt_me_entry->attr == NULL, classId=%d\n",__FUNCTION__,__LINE__,class_id);
			return 0;
		}

		if(msg_type == MT_OMCI_MSG_TYPE_GET || msg_type == MT_OMCI_MSG_TYPE_GET_CURR_DATA){
			ret = mallocTableBuffByGet(adpt_me_entry,me_info->attributes,me_info->mask);
			if(ret == -1){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] mallocTableBuffByGet fail. classId(%d)\n",__FUNCTION__,__LINE__,class_id);
				return -1;
			}
		}

		if(msg_type == MT_OMCI_MSG_TYPE_CREAT
			|| msg_type == MT_OMCI_MSG_TYPE_SET
			|| msg_type == MT_OMCI_MSG_TYPE_SET_TABLE
			|| msg_type == MT_OMCI_MSG_TYPE_GET
			|| msg_type == MT_OMCI_MSG_TYPE_GET_CURR_DATA)
		{
			if(me_info->attr_len < adpt_me_entry->attr->attrLen)
			{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] the Class id %d attr len(%d) is not enough(%d)\n",
					__FUNCTION__,__LINE__,class_id,me_info->attr_len,adpt_me_entry->attr->attrLen);
				return -1;
			}
		}	
    }
	memcpy(&current_me_info,me_info,sizeof(omci_me_info_t));
	switch(msg_type)
	{
		case MT_OMCI_MSG_TYPE_MIB_RESET:
			omci_me_mib_reset_op();
			omci_adpt_init_after_mibreset();
			gponmgr_lib_set_mib_flag(1);			
			syncTimeEnd = 0;
			break;
	    case MT_OMCI_MSG_TYPE_CREAT:
			pthread_mutex_lock(&omciGetAllData);
	        if(adpt_me_entry->func != NULL && adpt_me_entry->func->create_me != NULL)
	        {
	            ret = adpt_me_entry->func->create_me(adpt_me_entry, me_info);
	        }
			pthread_mutex_unlock(&omciGetAllData);
	        break;
	    case MT_OMCI_MSG_TYPE_DELETE:
	        if(adpt_me_entry->func != NULL && adpt_me_entry->func->delete_me!= NULL)
	        {
	            ret = adpt_me_entry->func->delete_me(adpt_me_entry, me_info);
	        }
	        break;
	    case MT_OMCI_MSG_TYPE_SET:
	    case MT_OMCI_MSG_TYPE_SET_TABLE:
			pthread_mutex_lock(&omciGetAllData);
	        if(adpt_me_entry->func != NULL && adpt_me_entry->func->set_attrs!= NULL)
	        {
	            ret = adpt_me_entry->func->set_attrs(adpt_me_entry, me_info);
	        }
			pthread_mutex_unlock(&omciGetAllData);
	        break;
	    case MT_OMCI_MSG_TYPE_GET:
	        if(adpt_me_entry->func != NULL && adpt_me_entry->func->get_attrs!= NULL)
	        {
	            ret = adpt_me_entry->func->get_attrs(adpt_me_entry, me_info);
	            //if(me_info->attributes != NULL)
	                //omciDumpContent(me_info->attributes,adpt_me_entry->attr->attrLen);
	        }
	        break;
		case MT_OMCI_MSG_TYPE_GET_CURR_DATA:
			if(adpt_me_entry->func != NULL && adpt_me_entry->func->get_cur_attrs != NULL)
			{
				ret = adpt_me_entry->func->get_cur_attrs(adpt_me_entry, me_info);
				//if(me_info->attributes != NULL)
	                //omciDumpContent(me_info->attributes,adpt_me_entry->attr->attrLen);
			}
			break;
		case MT_OMCI_MSG_TYPE_TEST:
			ret = omci_me_test_msg_hander(adpt_me_entry,me_info);
			break;
	    case MT_OMCI_MSG_TYPE_SYNC_TIME:
	        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]OLT set onu sync time\n", __FUNCTION__, __LINE__);
	        omci_me_sync_time_op();
	        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]OLT finish onu sync time\n", __FUNCTION__, __LINE__);
			if(me_info->attributes){
				sync_time_ptr = (omci_synchronize_time_t*)(me_info->attributes);
	        	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]Year:%d, Month:%d, Day:%d, Hour:%d, Minute:%d, Second:%d\n", __FUNCTION__, __LINE__,
					sync_time_ptr->year, sync_time_ptr->month, sync_time_ptr->dayOfMonth, sync_time_ptr->hourOfDay,
					sync_time_ptr->minuteOfHour, sync_time_ptr->secondOfMinute);
			}
	        break;
		case MT_OMCI_MSG_TYPE_REBOOT:
			omci_adpt_retoot_msg_handle(me_info);
			break;
	    default:
	        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"unkown msg type %d\n", msg_type);
	        break;
	}
end:
    
    if(adpt_me_entry != NULL && adpt_me_entry->special_flag)
        me_info->mask = 0;
	/*
    if(0 == ret){
    	omci_flow_me_handle(&current_me_info);
    }	
	*/
	memset(&current_me_info,0,sizeof(omci_me_info_t));
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d] ret = %d\n", __FUNCTION__, __LINE__, ret);
	return ret;
}


//900s
int omci_lib_adpt_update_pm_history_data()
{
    pm_history_data_list_ptr currNode = NULL;
    uint8_t len = 0;
    if(syncTimeEnd)
    {
        pmIntervalTimes++;
        endIntervalFlag = 1;
    }
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]PM internal end times = %d.\n",__FUNCTION__,__LINE__, pmIntervalTimes);
    pthread_mutex_lock(&pmListLock);
	currNode = pm_history_data_list;
    while(currNode != NULL)
    {
        if(!syncTimeEnd)
        {
             if(omci_pm_is_extend_pm_me(currNode->classId))
                len = 16+3;
            else
                len = 2+3;
            memset((uint8_t *)&currNode->pm_data+len, 0, sizeof(pm_history_data_buff_t)-len);
            memset(&currNode->pm_prev_data, 0, sizeof(pm_prev_data_buff_t));
        }
        omci_pm_get_history_data_from_drivers(currNode, syncTimeEnd);
        currNode = currNode->next;
    }
    pthread_mutex_unlock(&pmListLock);
    return 0;
}

static void omci_set_wan2lan_cmd(void)
{
    char buff[16] = {0};

    omci_tcapi_nget("OMCI_Entry","wan2lan",buff,sizeof(buff));

    if(strcasecmp(buff, "yes") == 0)
    {
        omciScreenPrintf("[%s][%d] set wan2lan to capture omci\n",__FUNCTION__,__LINE__);
        system("sys wan2lan on 15");
    }
}

static int omci_cfg_onu_portmap(void){
	char buffer[128] = {0};
	char *fir = NULL;
	char *fir1 = NULL;
	char *tbuffer = NULL;
	char *tbuffer1 = NULL;
	uni_port_info_t port_map[OMCI_MAX_PORTS];
	int idx = 1;

	strncpy(port_map[0].dev_name,"pon",DEV_NAME_LEN-1);
	port_map[0].unit_type = 48;
	port_map[0].eth_type = 2;
	
#ifdef TCSUPPORT_OPENWRT
	omci_lib_uci_get("gpon.ONU.PortMap", buffer, sizeof(buffer));
#else
	omci_tcapi_nget("GPON_ONU", "PortMap", buffer, sizeof(buffer));
#endif
	
	if(strlen(buffer) == 0){
		return -1;
	}
	
	fir = strtok_r(buffer, " ", &tbuffer);
	while(fir){
		fir1 = strtok_r(fir, ",", &tbuffer1);
		strncpy(port_map[idx].dev_name,fir1,DEV_NAME_LEN-1);
		fir1 = strtok_r(NULL, ",", &tbuffer1);
		port_map[idx].unit_type = atoi(fir1);
		fir1 = strtok_r(NULL, ",", &tbuffer1);
		port_map[idx].eth_type = atoi(fir1);
		
		fir = strtok_r(NULL, " ", &tbuffer);
		idx++;
	}
	memcpy(omci_info_g.omci_port_map , port_map, sizeof(port_map));
	
	if(-1 == blapi_pon_set_port_map_info(idx, port_map)){
		printf("blapi_pon_set_port_map_info fail\n");
		return -1;
	}
	
    return 0;
}

int omci_lib_adpt_set_pon_start( void )
{
    ponLinkUpInfo_t regInfo;
    char buffer[GPON_REG_ID_LENS] = {0};
    unsigned long vssn = 0;
    int onuMode = 0;
    
    memset(&regInfo,0, sizeof(ponLinkUpInfo_t));
	/*this part of the initialization is based ont the fact that the relevant ko files has been loaded*/
	omci_adpt_init_after_onu_ready();

	/*configure the internet created ME information into the gpon flow module*/
	omci_flow_cfg_gpon_flow();
    omci_set_wan2lan_cmd();
	
	omci_cfg_onu_portmap();

    omci_lib_get_sn_mem(buffer,sizeof(buffer));
	memcpy((char *)regInfo.sn, buffer, 4);
	vssn = strtoul(buffer+4, NULL, 16);
	regInfo.sn[4] = (unsigned char)(vssn >> 24) ;
	regInfo.sn[5] = (unsigned char)(vssn >> 16) ;
	regInfo.sn[6] = (unsigned char)(vssn >> 8) ;
	regInfo.sn[7] = (unsigned char)(vssn) ;
    omci_lib_get_passwd_mem(regInfo.password,GPON_PASSWD_LENS);
	omci_lib_get_regid_mem(regInfo.reg_id,GPON_REG_ID_LENS);
    omci_lib_get_link_mode((onu_link_mode_t *)&onuMode);
	if(blapi_pon_set_link_up(onuMode, regInfo) != 0) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci_lib_adpt_set_pon_start fail!\r\n ");
		return -1;
	}
	return 0;
}

/*this hook function is used to obtain relevant information after the completion of the ploam interaction,for 
example:ONU id*/
int omci_lib_adpt_get_ploam_info(ploam_info_t *info)
{
	uint16_t response_time = 0;
	uint16_t total_tcont_num = 0;
	FILE *fp = NULL;
	char line[128] = {0};
	float timeSec = 0.0;
	uint32_t sysUpTime = 0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d] \n", __FUNCTION__, __LINE__);
	if(NULL == info){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omci_lib_get_total_tcont_num(&total_tcont_num);
	if(GPON_TCONT_MAX_NUM == total_tcont_num){
		info->onu_id = omci_info_g.onuId;
	}else{
		info->onu_id = DO_NOT_REPORT_OMCC_TCONT;
	}

    if(omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_GPON || omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_AUTO)
    {
        gponmgr_lib_get_response_time(&response_time);
        response_time = response_time * 32 * 1000/1244; // unit 32bit, 1.244Gbps
    }
	else if (omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_GPON_SYM) {
		gponmgr_lib_get_response_time(&response_time);
        response_time = response_time * 32 * 1000/2488; // unit 32bit, 2.488Gbps
	}
    else
    {
        xgponmgr_lib_get_onuRespTime(&response_time);
        if(omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_XGSPON 
			|| omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_NGPON2_10G_10G)
            response_time = response_time * 64 *1000 / 9953;       // unit 64bit, 9.95328Gbps
        else if(omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_XGPON
			|| omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_NGPON2_10G_2G
			|| omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_NGPON2_2G_2G)
            response_time = response_time * 64 * 1000/2488; //// unit 64bit, 2.48832Gbps
        else
            response_time = 35000;
    }
	
	info->response_time = response_time;
	if(info->response_time > 36000){
		info->response_time = 36000;
	}else if(info->response_time < 34000){
		info->response_time = 34000;
	}
	if ((fp = fopen("/proc/uptime", "r")) == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] fopen fail\n", __FUNCTION__, __LINE__);
		return -1;
	}
	if (fgets(line, 128, fp) == NULL){
		fclose(fp);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] fgets fail\n", __FUNCTION__, __LINE__);
		return -1;
	}
	sscanf(line, "%f",&timeSec);

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"timeSec = %f\n", timeSec);
	sysUpTime = (uint32_t)(timeSec * 100); /*10 ms interval*/
	omci_lib_set_sys_up_time(sysUpTime);
	fclose(fp);

	return 0;
}

int omci_lib_adpt_set_event_monitor(uint32_t event_id_mask)
{
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
	g_event_mask = event_id_mask;

	return 0;
}

int omci_lib_adpt_get_softimage_version(char *version, uint8_t ver_len, uint8_t image_flag)
{
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
    return omci_image_get_version(version, ver_len, image_flag);
}
int omci_lib_adpt_get_bootflag(uint8_t * pbootflag)
{
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
    return omci_image_get_bootflag(pbootflag);
}
int omci_lib_adpt_set_bootflag(uint8_t bootflag)
{
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
    return omci_image_set_bootflag(bootflag);
}
int omci_lib_adpt_save_softimage_state(softimage_state_t *softimage_state)
{
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
    return omci_image_save_state(softimage_state);
}
int omci_lib_adpt_read_softimage_state(softimage_state_t *softimage_state)
{
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
    return omci_image_read_state(softimage_state);
}

int omci_lib_adpt_get_current_image_version(char *version,uint8_t ver_len, char *image_path)
{
	char cmd_buf[128];
	FILE* fp = NULL;
	int i = 0;
	uint16_t len = 0;
	int ret = -1;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
	if((NULL == version)||(ver_len < 14)||(NULL == image_path)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	memset(cmd_buf,0,sizeof(cmd_buf));
	fp = fopen(image_path,"r");
	if (fp != NULL)
	{
		unsigned int secureboot_en = 0;
		ret = blapi_system_get_secureboot_en(&secureboot_en);
		if(ret != 0) {
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]:blapi_system_get_secureboot_en fail.\n",__FUNCTION__,__LINE__);
			goto end;
		}
		
		if(secureboot_en) {
			ret = fseek(fp,ARM_SECURE_BOOT_LEN,SEEK_SET);		
			if(ret != 0)	{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]:fseek fail.\n",__FUNCTION__,__LINE__);
				goto end;
			}
		}

		len = fread(cmd_buf,1,80,fp);
		if (len > 0)   //please see trx header: 48 is offset of custom version
		{
			len = 0;
			for( i=0;i < ver_len ;i++)
			{
				if(cmd_buf[i+16] < 0x20)
				{
					cmd_buf[i+16]  = 0;
					break;
				}
			}
			len = i + 1;
			len = (len < ver_len) ? len:ver_len;
			memcpy(version,&cmd_buf[16],len);
		}else{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]:fread fail.\n",__FUNCTION__,__LINE__);
			ret = -1;
			goto end;
		}
	}else{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]:fopen fail.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	ret = 0;
end:	
	fclose(fp);
	return ret;
}


int omci_lib_adpt_is_current_image_valid(char *image_path,uint32_t olt_crc_val)
{
    uint32_t crc_test = 0xFFFFFFFF;
    FILE* fp = NULL;
    long imageSize = 0;
    uint32_t readLen = 0;
    int ret=0;
    struct trx_header *trx = NULL;
    char imageBuff[1024] = {0};
    uint32_t i = 0;
	uint32_t size_remain = 0;
	uint32_t size_read = 0;
	unsigned int secureboot_en = 0;

    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
    if(NULL == image_path){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    fp = fopen(image_path,"r");
    if(fp == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]open file failed.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    fseek(fp, 0, SEEK_END);
    imageSize = ftell(fp);
    if(imageSize <= 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: imageSize is zero, fail.\n",__FUNCTION__,__LINE__);
        ret = -1;
        goto closeFile;
    }

    trx = (struct trx_header *)(calloc(1,sizeof(struct trx_header)));
    if(trx == NULL){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: malloc trx header buffer fail.\n",__FUNCTION__,__LINE__);
        ret = -1;
        goto closeFile;
    }

	ret = blapi_system_get_secureboot_en(&secureboot_en);
	if(ret != 0) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]:blapi_system_get_secureboot_en fail.\n",__FUNCTION__,__LINE__);
		goto closeFile;
	}
	if(secureboot_en)
		fseek(fp, ARM_SECURE_BOOT_LEN, SEEK_SET);
	else
		fseek(fp, 0, SEEK_SET);

    readLen = fread(trx, 1, sizeof(struct trx_header), fp); 
    if (readLen != sizeof(struct trx_header))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: fread fail, fileSize=%x,trx_header size=%lu\n",__FUNCTION__,__LINE__,readLen,sizeof(struct trx_header));
        ret = -1;
        goto closeFile;
    }

    /*Calculate the CRC32 of the softimage that removes trx_header*/
	size_remain = trx->len - trx->header_len;
    while(!feof(fp)){
		if(size_remain <= 0)
			break;
		
		if(size_remain >= sizeof(imageBuff))
			size_read = sizeof(imageBuff);
		else
			size_read = size_remain;
		
        memset(imageBuff, 0 ,sizeof(imageBuff));
        readLen = fread(imageBuff, 1, size_read, fp);
        if(readLen == 0){
            break;
        }
		size_remain -= readLen;

        for(i = 0; i < readLen; i++){
            crc_test = UPDC32(imageBuff[i], crc_test);
        }
    }

	if(trx->crc32 != crc_test){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: crc check Error!!!  trx->crc32=0x%x,crctest=0x%x\n",__FUNCTION__,__LINE__,trx->crc32,crc_test);
        ret = -1;
        goto closeFile;
    }   

closeFile:
    fclose(fp);
    if(trx != NULL)
        free(trx);
            
    return ret;
}
int omci_lib_adpt_write_image(uint8_t image_flag, char* image_path)
{
	char cmd_buf[128];
	struct stat buf;
#ifndef TCSUPPORT_OPENWRT
	uint32_t offset=0;
#endif
	uint32_t fileLength = 0;
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
	if(NULL == image_path){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	if(stat(image_path, &buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]stat fail.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	
	if(blapi_pon_secure_boot(image_path) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]blapi secure boot fail.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	
	fileLength = buf.st_size;
#ifndef TCSUPPORT_OPENWRT
	offset = 0;
#endif
	memset(cmd_buf, 0, sizeof(cmd_buf));
	if(image_flag == 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "startWriteImage:---write main image to flash!\n");
#ifdef TCSUPPORT_OPENWRT
		sprintf(cmd_buf,"/lib/upgrade/omciupgrade %s", image_path);
#else
		sprintf(cmd_buf,"/userfs/bin/mtd -f write %s %d %d %s",image_path, fileLength, offset ,"tclinux");
#endif
	
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "startWriteImage:---write slave image to flash!fileLength = %d\n", fileLength);
#ifdef TCSUPPORT_OPENWRT
		sprintf(cmd_buf,"/lib/upgrade/omciupgrade %s", image_path);
#else
		sprintf(cmd_buf,"/userfs/bin/mtd -f write %s %d %d %s",image_path, fileLength, offset ,"tclinux_slave");
#endif
	}
	system(cmd_buf);
	
    return 0;
}

int omci_lib_adpt_enhanced_security_ctrl_set_msk(uint8_t *msk, uint8_t msk_len)
{
    if(xgponmgr_lib_set_msk(msk) != 0) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]XGPON Set msk fail.\n",__FUNCTION__,__LINE__);
		return -1;
	}
    return 0;
}

int omci_lib_adpt_generate_random_data(uint8_t *random_val)
{
	int fd = 0, len = 0;

	if(NULL == random_val){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	if((fd = open("/dev/urandom",O_RDONLY)) < 0){
		perror("open /dev/urandom error!\n");
		return -1;
	}else if((len = read(fd,random_val,sizeof(uint8_t))) < 0){
		perror("/dev/urandom : read error!\n");
		close(fd);
		return -1;
	}
	close(fd);
    return 0;
}

int omci_lib_adpt_table_mem_free(omci_me_info_ptr me_info)
{
	management_entry_t *adpt_me_entry = NULL;
	uint16_t offsetOfStruct=0;
	int i=0;
	omci_table_attr_ptr tablePtr=NULL;
	static int cnt=0;

	if(NULL == me_info){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		return -1;
	}

	adpt_me_entry = getAdptMeEntryByClassId(me_info->class_id);
	if(adpt_me_entry == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]the classId(%d) can not get the entry.\n",__FUNCTION__,__LINE__, me_info->class_id);
		return -1;
	}

	if(adpt_me_entry->attr == NULL )
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] adpt_me_entry->attr == NULL, classId=%d\n",__FUNCTION__,__LINE__,me_info->class_id);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: classId=%d, mask=0x%x\n",__FUNCTION__,__LINE__,me_info->class_id,me_info->mask);

	offsetOfStruct += 2; //2bytes instanceId
	for( i = 1; i <= 16; i++){
		if(adpt_me_entry->omci_attr_dscp_list[i].attriIndex == 255)
			   break;

		if( (me_info->mask >> (16 - i) & 0x0001)
			&& (adpt_me_entry->omci_attr_dscp_list[i].format == ATTR_FORMAT_TABLE))
		{
			tablePtr = (omci_table_attr_ptr)(me_info->attributes + offsetOfStruct);

			if(tablePtr != NULL && tablePtr->buf != NULL ){
			   free(tablePtr->buf);
			   tablePtr->buf = NULL;
			   omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] free table ptr, cnt=%d\n",__FUNCTION__,__LINE__,++cnt);
			}
		}

		//calculate offset
		if(adpt_me_entry->omci_attr_dscp_list[i].format == ATTR_FORMAT_TABLE){
			offsetOfStruct	+= sizeof(omci_table_attr_t); // table attibute is defined as struct ,include table pointer and table size
		}
		else{
			offsetOfStruct += adpt_me_entry->omci_attr_dscp_list[i].attriLen;
		}
	}
    return 0;
}
int omci_lib_adpt_screen_print(char *content)
{
	FILE *proc_file;

	if(content == NULL)
		return -1;

	proc_file = fopen("/proc/tc3162/dbg_msg", "w");
	if (!proc_file ) {
		return -1 ;
	}

	fprintf(proc_file, "%s", content);
	fclose(proc_file);

	return 0;
}
omci_lib_adpt_hook_t omci_lib_adpt_hook_function = {
	omci_lib_adpt_socket_receive,
	omci_lib_adpt_socket_transmit,
	omci_lib_adpt_pkt_handler,
	omci_lib_adpt_set_pon_start,
	omci_lib_adpt_get_ploam_info,
	omci_lib_adpt_update_pm_history_data,
	omci_lib_adpt_set_event_monitor,
	omci_lib_adpt_get_softimage_version,
	omci_lib_adpt_get_bootflag,
	omci_lib_adpt_set_bootflag,
	omci_lib_adpt_save_softimage_state,
	omci_lib_adpt_read_softimage_state,
	omci_lib_adpt_get_current_image_version,
	omci_lib_adpt_is_current_image_valid,
	omci_lib_adpt_write_image,
	omci_lib_adpt_enhanced_security_ctrl_set_msk,
	omci_lib_adpt_generate_random_data,
	omci_lib_adpt_table_mem_free,
	omci_lib_adpt_screen_print,
	omci_adpt_stop_timer,
	omci_attr_get_all_data_except_table_attr,
};

#ifdef TCSUPPORT_OMCI_ALCATEL
/* ONT issues this AVC periodically, and expects OLT to send */
/* the matching Handshake AVC Response. */
static int omci_adpt_period_avc_tmout(void)
{
	static uint32_t oneSecPeriodicRound = 0;
	char periodEnable[10] = {0};
	char periodRound[10] = {0};
	uint8_t round = 0;
	char nodeName[32]={0};
    evt_avc_data_t avc_info = {0};

	strcpy(nodeName, "GPON_ONU");
	if(omci_tcapi_nget(nodeName, "PeriodEnable", periodEnable,sizeof(periodEnable)) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, " %s[%d]:get PeriodEnable,  fail \n",__FUNCTION__, __LINE__);
	}
	if(omci_tcapi_nget(nodeName, "PeriodRound", periodRound,sizeof(periodRound)) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, " %s[%d]:get periodRound,  fail \n",__FUNCTION__, __LINE__);
	}
	round = atoi(periodRound);
	if (!strcmp(periodEnable, "1"))
	{
		oneSecPeriodicRound++;
		if (oneSecPeriodicRound%round == 0)
		{
			avc_info.class_id = 0xFF10; //ALU ONT Generic V2 ME
			avc_info.inst_id = 0x0000;
			omci_adpt_report_event(OMCI_EVENT_AVC, &avc_info);
			oneSecPeriodicRound = 0;
		}
	}
	return 0;
}
#endif

int omci_lib_adpt_init_func_hook(omci_lib_adpt_hook_t **adpt_hook_pptr)
{
	int ret = 0;
	extendOmciFlag = 0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d] \n", __FUNCTION__, __LINE__);

	/*Initializes the compile options variable*/
    init_compileoption_val();

	/*Initialize the ability to check for memory leaks*/
#ifdef MEMORY_DEBUG
	ret = init_check_memory();
	if(ret < 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci main NodelistLockInit fail!\r\n ");
		return -1;
	}
#endif

	/*Initializes the standard ME table for the current Adapter*/
    omci_adpt_init_std_omci_map();

	/*Initialize the ME table related to the GPON flow in Adapter*/
	omci_flow_init_me_map();

	/*mount the OMCI framework standard hook interface functions*/
	if(adpt_hook_pptr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"adpt_hook_pptr is NULL, fail!\r\n ");
		return -1;
	} else {
		*adpt_hook_pptr = &omci_lib_adpt_hook_function;
	}
	
	/*mount non-standard ME tables in the OMCI framework*/
#ifdef SUPPORT_PRIVATE_OMCI
	omci_add_vendor_me = omciAddVendorMeToStdMeTable;
#endif

	/*Init software upgrade action hooks.*/
	omciActionStartSwDownload = omciStartSwDownloadAction;
	omciActionDownloadSec = omciDownloadSecAction;
	omciActionEndSwDownload = omciEndSwDownloadAction;
	omciActionActiveSw = omciActiveSwAction;
	omciActionCommitSw = omciCommitSwAction;

#ifdef TCSUPPORT_OMCI_ALCATEL
	timer_id_avc_period = timerPeriodicStartS(1000, (TimerCallback)omci_adpt_period_avc_tmout, NULL);
	if (timer_id_avc_period != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, " timer_id_avc_period == TIMER_ID_NULL\n");
		return -1;
	}
#endif

	/*Initializes the socket used to receive and send the OMCI*/
	if(omci_adpt_socket_init() != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR," omciSocketInit fail\r\n");
        return -1;
	}

	/*Initial OMCI message  rx counters*/
	memset(&OmciPktRxCnt, 0, sizeof(OmciPktRxCnt_t)) ;
	
	omci_get_pm_info = omci_test_pm_info;
  
	ret = pthread_mutex_init(&omciHandlePonIfc, NULL);
	if(ret < 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci handlePonIfc pthread_mutex_init fail!\r\n ");
		return -1;
	}

	ret = pthread_mutex_init(&omciSetMBPDevId, NULL);
	if(ret < 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci omciSetMBPDevId pthread_mutex_init fail!\r\n ");
		return -1;
	}
	
	ret = pthread_mutex_init(&pmListLock, NULL);
	if (ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci pmListLock pthread_mutex_init fail!\r\n ");
		return -1;
	}

	ret = pthread_mutex_init(&omciGetAllData,NULL);
	if (ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"omci omciGetAllData pthread_mutex_init fail!\r\n ");
		return -1;
	}

	ponmgr_lib_register_event_handler(EVT_HANDLER_OMCI);

	//reset voip Config
	if(omci_voip_set_config_method_used(OMCI_VOIP_CFG_DATA_CFG_METHOD_NOT_USED) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: reset voipConfig  fail\n",__FUNCTION__,__LINE__);
	}

	gponmgr_lib_get_bbf247_flag(&bbf247_enable);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"bbf247_enable=%d\r\n",bbf247_enable);

	return ret;
}

static int omci_adpt_init_after_onu_ready(void)
{
	 /*After config done!*/
    omci_adpt_init_omci_info_variable();    
    omci_adpt_get_olt_type();
	/*After ONU ready!*/
	if(TCSUPPORT_PON_IP_HOST_VAL){	
		omci_adpt_init_ip_host_wan_interface();
	}
	/*ONU automatically  create OMCI_CLASS_ID_PPTP_ETHERNET_UNI one instance  */
	omci_adpt_init_pptp_ether_uni();
    omci_adpt_init_priority_queue();
	omci_adpt_init_Loop_Detection();
	if(omci_adpt_init_trap_handler() != 0){
		exit(0) ;
	}
	memset(&ani_uni_port,0,sizeof(ani_uni_port));
	memset(&ani_gemport,0,sizeof(ani_gemport));

	init_voip_config();
	ubus_client_init();
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: done! \n", __FUNCTION__, __LINE__);
	return 0;
}

int omci_lib_adpt_denit_func_hook(void)
{
#ifdef MEMORY_DEBUG
	deinit_check_memory();
#endif
#ifdef TCSUPPORT_OMCI_ALCATEL
	timerPeriodicStop(timer_id_avc_period);
	timer_id_avc_period = 0;
#endif
    omci_adpt_commit_node_list_destory();
	timer_exit();
	omci_adpt_trap_destory();
	omci_adpt_socket_destroy();
	pthread_mutex_destroy(&omciHandlePonIfc);
	pthread_mutex_destroy(&pmListLock);
	pthread_mutex_destroy(&omciSetMBPDevId);
	pthread_mutex_destroy(&omciGetAllData);
	return 0;
}


int omciSaveEvent(int eventId){

	char data[48] = {0};
	static uint32_t currentIndex = 1;
	static uint8_t omciRestart = 1;
	int currfilesize = 0;
	char *indexStr = NULL;
	size_t len = 0;
	char cmd[32] = {0};
	char path[32] = {0};
	FILE* fp = NULL;
	struct timeval time;
	struct stat buf;
	int hsec = 0;
	int msec = 0;
	int ssec = 0;
	int mmsec = 0;
	int usec = 0;
	int ret = 0;

	if(isIndexFileNotExist(OMCI_EVENT_INDEX_PATH)){
		fp = fopen(OMCI_EVENT_INDEX_PATH, "w+");
		if(NULL == fp){
			omcidbgBytePrintf("open file failed!");
			return -1;
		}
		fclose(fp);
		memset(cmd, 0, sizeof(cmd));
		sprintf(cmd, "echo 1 > %s",OMCI_EVENT_INDEX_PATH);
		system(cmd);
	}

	if(omciRestart){
		omciRestart = 0;
		fp = fopen(OMCI_EVENT_INDEX_PATH, "r");
		if(NULL == fp){
			omcidbgBytePrintf("open file failed!");
			return -1;
		}
		
		ret = getline(&indexStr, &len, fp);
		fclose(fp);
		if(ret <= 0)
		{
			if(indexStr != NULL)
			{
				free(indexStr);
			}
			omcidbgBytePrintf("read index failed!");
			return -1;
		}
		else{
			if(indexStr != NULL)
			{
				currentIndex = atoi(indexStr);
				free(indexStr);
			}
			else{
				omcidbgBytePrintf("read index failed!");
				return -1;
			}
		}
	}

	sprintf(path, "/tmp/omciEvent%05u.txt", currentIndex);
	fp = fopen(path, "a+");
	if(NULL == fp){
		omcidbgBytePrintf("open file failed!");
		return -1;
	}

	MACRO_XPON_COMMON_READUPTIME(&time);
	hsec = time.tv_sec / 3600;
	msec = (time.tv_sec % 3600)/60;
	ssec = (time.tv_sec % 3600)%60;
	mmsec = time.tv_usec / 1000;
	usec = time.tv_usec % 1000;

	switch(eventId){
		case XMCS_EVENT_GPON_LOS:
			sprintf(data, "%02d:%02d:%02d:%03d:%03d Event = %s\n",hsec, msec, ssec, mmsec, usec, "Los");
			break;
		case XMCS_EVENT_GPON_PHY_READY:
			sprintf(data, "%02d:%02d:%02d:%03d:%03d Event = %s\n",hsec, msec, ssec, mmsec, usec, "Ready");
			break;
		case XMCS_EVNET_GPON_DEACTIVATE:
			sprintf(data, "%02d:%02d:%02d:%03d:%03d Event = %s\n",hsec, msec, ssec, mmsec, usec, "Deactivate");
			break;
		case XMCS_EVENT_GPON_ACTIVATE:
			sprintf(data, "%02d:%02d:%02d:%03d:%03d Event = %s\n",hsec, msec, ssec, mmsec, usec, "activate");
			break;
		case XMCS_EVENT_GPON_DISABLE:
			sprintf(data, "%02d:%02d:%02d:%03d:%03d Event = %s\n",hsec, msec, ssec, mmsec, usec, "Disable");
			break;
		case XMCS_EVENT_GPON_ENABLE:
			sprintf(data, "%02d:%02d:%02d:%03d:%03d Event = %s\n",hsec, msec, ssec, mmsec, usec, "Enable");
			break;
		default:
			break;
	}

	fwrite(data, 1, strlen(data), fp);
	fclose(fp);

	ret = stat(path, &buf);
	if(ret){
		return -1;
	}
	currfilesize = buf.st_size;
	if(currfilesize >= OMCI_SAVE_EVENT_MAX_SIZE){
		currentIndex++;
		memset(cmd, 0, sizeof(cmd));
		sprintf(cmd, "echo %u > %s", currentIndex, OMCI_EVENT_INDEX_PATH);
		system(cmd);
		if(currentIndex > OMCI_SAVE_EVENT_FILE_TOTAL_NUM){
			memset(cmd, 0, sizeof(cmd));
			sprintf(cmd,  "rm -rf /tmp/omciEvent%05d.txt", currentIndex - OMCI_SAVE_EVENT_FILE_TOTAL_NUM);
			system(cmd);
		}
	}

	return 0;
}


int omci_adpt_get_pm_pre_data(uint16_t classId, uint16_t instId, void *data, int dataSize)
{
	int ret = -1;
	pthread_mutex_lock(&pmListLock);
	pm_history_data_list_ptr currNode = pm_history_data_list;
	
	while(currNode != NULL)
	{
		if((currNode->classId == classId) && (currNode->instId== instId))
		{
		    memcpy(data, &currNode->pm_prev_data, dataSize);
		    ret = 0;
		    break;
		}
		else
		{
		    currNode = currNode->next;
		}
	}
	pthread_mutex_unlock(&pmListLock);
	
	return ret;
}

uint8_t xsi_lanport_info_covert(uint8_t port)
{			
	if(strcmp(omci_info_g.omci_port_map[port].dev_name, "eth0.8") == 0){			
		port = eth_hsgmii;            //from  proc/tc3162/hsgmii_idx   		
	}else if(strcmp(omci_info_g.omci_port_map[port].dev_name, "eth0.7") == 0){			
		port = pcie1_hsgmii;			//from  proc/tc3162/hsgmii_idx   pcie1_hsgmii		
	}else if(strcmp(omci_info_g.omci_port_map[port].dev_name, "eth0.6") == 0){			
		port = pcie0_hsgmii;			//from  proc/tc3162/hsgmii_idx	 pcie0_hsgmii		
	}else if(strcmp(omci_info_g.omci_port_map[port].dev_name, "eth0.5") == 0){			
		port = usb_hsgmii;			//from  proc/tc3162/hsgmii_idx	 usb_hsgmii		
	}			

	return port;	
}


